La Escala del Universo

Utiliza la barra de desplazamiento para moverte por un recorrido a lo largo de todos los tamaños posibles: desde la partícula subatómica hasta el universo conocido.

Éste es un interesante juego de imágenes y comparaciones para darse una idea de cómo son las cosas…

Escala del universo(Link externo)

Vía microsiervos.

 

Programación PIC 16F84A

En este post voy a intentar hacer un breve repaso a todo lo que he necesitado para programar un PIC. El PIC en cuestión es un 16F84A (datasheet) y tiene las siguientes patillas:

Esquema PIC16F84A

No voy a entrar en detalles sobre cuales son las características del microcontrolador, porque sobre eso hay muchísima información en internet. De lo que sí hablaré es de como programarlo.

Todo lo que he necesitado ha sido:

  • Un PIC 16F84A, obvio.
  • Un programador de PICs. En mi caso, he utilizado un TE-20. Es un programador bastante común, que se puede comprar o montar, ya que el esquema se encuentra fácilmente en google. Es un programador que no necesita alimentación externa.
  • Varios componentes básicos para montar un circuito de pruebas y ver que, efectivamente, el PIC se había programado.
  • El software PIC C Compiler. Necesario para escribir código en C y compilarlo, obteniendo así un archivo con extensión .hex
  • El software IC-Prog  (gratuito). Necesario para volcar el archivo .hex en la memoria interna del PIC.

Ahora que esto ya está claro, empecemos:

Lo primero de todo es crear el programa que grabaremos. Este programa será extremadamente sencillo: encenderá un LED conectado y lo apagará repetidamente. Para crear el programa con el PIC C Compiler, necesitamos crear un nuevo proyecto indicando nuestro modelo de PIC (16F84A) y la frecuencia del oscilador. En este caso, 4Mhz. El código en cuestión del programa es:

#include «main.h»        // fichero creado por el PIC C Compiler.
#byte port_b=0x06  // direccion fisico del puerto B en el registro.

void main()
{
set_tris_b(0);    // configura el puerto B como salida.
port_b = 0;         // apaga el puerto B.

while(true) {
delay_ms(500);  // espera 500 ms.
port_b = 0xff;      // enciende el puerto B.
delay_ms(500);
port_b = 0x00;
}
}

Una vez que hemos compilado el código y hemos obtenido el archivo .hex, el siguiente paso es volcar ese archivo a la memoria del PIC. Para ello, utilizamos el programador TE-20:

Programador TE-20

Se puede ver que el PIC está montado en un zócalo (es el único microchip que se ve). Los otros dos zócalos son para programar memorias EEPROMs y PICs con más patillas. En este caso no las necesitamos.

Una vez que el TE-20 está conectado al puerto serie del ordenador, con el software IC-Prog lo programaremos. Para ello, detectamos primero en que puerto COM está conectado el programador TE-20, cargamos el programa .hex y lo grabamos. Las opciones (Settings > Hardware) que hay que configurar para que este programador en particular funcione están en la imagen (hay que fijarse en que el programador seleccionado es el JDM y que está seleccionada la casilla invert VCC).

IC-Prog 16F84A

También hay que observar que hemos seleccionado el PIC correcto. Las casillas de la derecha del programa principal son los fuses, unos registros especiales que manejan ciertas cosas. Mientras el WDT (Watch Dog) esté desactivado, no hay problema.

Con el PIC grabado con nuestro programa, ya podemos probarlo en un circuito. Yo he utilizado el siguiente esquema:

Esquema prueba 16F84A

Notemos que faltan las conexiones de alimentación del PIC (VDD a 5v  y VSS a masa)

En realidad, el LED se podría conectar en cualquiera de los pines marcados como del puerto B, ya que en el programa se activan todos. Para la alimentación he utilizado 4 pilas AA (de las normales, vamos). Para acabar, una foto con el circuito montado y el LED encendido:

Circuito prueba 16F84A

Podéis encontrar todos los archivos necesarios para programar el PIC (código fuente y archivo .hex) aqui:

Parpadeo LED (Ejemplo código PIC)
1.9 KiB
233 Downloads
Details

Quadcóptero VI: Motores y hélices

He estado mirando sitios en los que conseguir motores y hélices, y al final me he decido por comprarme 4 motores hexTronik 24gram Brushless Outrunner 1700kv y un pack de hélices 6050SF & R6050SF.

Los motores tienen las siguientes características:

  • Deben ser alimentados con 7.2 V, con corriente trifásica, ya que son motores Brushless.
  • Tienen una RPM/v de 1700. Esto quiere decir que sin carga (sin hélices ni nada) giran a 1700 RPM (revoluciones por minuto) por cada voltio que se le aplica.
  • Pesan 24g cada uno.

Se recomienta que el RPM/v del motor sea el menor posible, ya que así se consume menos energía y produce menos vibraciones (que debemos evitar para obtener lecturas correctas de los sensores de estabilización). Este en concreto no tiene un valor muy bajo (1700 no es demasiado bajo… ya que existen motores con 750 RPM/v). No obstante, su precio, su peso, y el hecho de que necesiten 7.2V me ha hecho decantarme por este modelo.

Las hélices, por su parte, tienen las siguientes características:

  • Tal y como dice su nombre (6050), son hélices 6×5. Esto es, tienen 6 pulgadas de diámetro y 5 de paso (en inglés, blade pitch o simplemente pitch)
  • Pesan unos 5g cada una.

Si ponemos nuestra hélice horizontalmente paralela al suelo, el paso se define como la distancia en vertical que recorrería en una vuelta completa si girara en un sólido. Puede que el concepto de ángulo de paso (pitch angle) ayude a comprender de qué se trata:

Imagen explicativa sobre el pitchNo son hélices de gran calidad, por lo que quizás habrá que compensarla un poco para evitar vibraciones. Esto se puede hacer fácilmente colocando gotitas de pegamento en los extremos de las mismas o simplemente cortando trocitos que no alteren demasiado la aerodinámica.

Ahora solo falta esperar a ver cuando llegan…

Inteligencia Artificial III: Chatbots

Un chatbot  (o bot conversacional) es un programa informático preparado para mantener conversaciones lógicas y coherentes. Según la wikipedia,

(…) la mayoría de los bot conversacionales no consiguen comprender del todo. En su lugar, tienen en cuenta las palabras o frases del interlocutor, que les permitirán usar una serie de respuestas preparadas de antemano. De esta manera, el bot es capaz de seguir una conversación con más o menos lógica, pero sin saber realmente de qué está hablando.

Es decir, se mantiene un enfoque muy parecido al que comentaba en el primer post sobre IA. He estado investigando y he encontrado una gran variedad de chatbots con los que se puede conversar por internet (probablemente, para aumentar las capacidades de aprendizaje del bot). Estos son algunos de los que se pueden encontrar:

  • CleverBot es uno de los más famosos.
  • Jabber Wacky es otro del mismo programador.
  • ALICE está escrito en Java.
  • Eliza es un bot algo antiguo (1966) pero bastante potente para su época. Tiene una nueva versión, Dr. Abuse, de la que no he encontrado versión online.
  • …y una gran cantidad de otros programas parecidos.

Los he probado un poco, y me he dado cuenta de que su única función es imitar, pero en ninguno momento he tenido la sensación de que puedan tener alguna utilidad. Un claro ejemplo de esto es que ante la pregunta «What is faster, a train or a turtle?», todos contestaban con frases vacías o me lo preguntaban a mi… lo cual me decepciona un poco.

¿De qué sirve tener un chatbot si no te puede aportar información ni ayudar de ninguna manera? ¿por qué hay gente que se esfuerza tanto en conseguir cosas que no van a servir de nada más que de pasar el test de turing?. Citando otra vez a la wikipedia,

[El test de turing] se fundamenta en la hipótesis positivista de que, si una máquina se comporta en todos los aspectos como inteligente, entonces debe ser inteligente.

Es una afirmación con la que estoy totalmente de acuerdo, y eso hace que para mi sea imposible considerar que alguno de los bots antes mencionados pueda pasar el test de turing, ya que no se comportan como inteligentes.

Creo se debería cambiar el objetivo de los chatbots. No hay que orientarlos a ser capaces de pasar el test de turing, sino que hay que orientarlos a ser inteligentes. Y pasar el test ya vendrá solo.

Inteligencia Artificial II: Aprendizaje e inteligencia

El otro día hablaba de mi enfoque sobre la inteligencia artificial. Hoy prentendo concretar un poco más mis ideas. Puede que si algún día tengo tiempo me dedique a programar algo y ver si da resultado.

Creo que es necesario crear un programa con un autoaprendizaje de su entorno y, por tanto, crear un entorno. Evidentemente, el entorno debe ser un programa que ejecute al programa de la IA (o simplemente una entrada/salida de carácteres). Se debe encargar de interactuar con la IA y ofrecerle premios o castigos que refuercen el aprendizaje (mediante una llamada a un procedimiento preprogramado de la IA, por ejemplo).

Por su parte, la IA debe disponer de:

  • Una entrada/salida de carácteres, que será el mecanismo básico de comunicación.
  • Otra entrada en la que se le pueda indicar si su salida ha sido coherente o no, para reforzar el aprendizaje (a modo de premios y castigos).
  • Una estructura de datos que le permita:
    • Inducir conocimiento nuevo a partir de conocimiento existente.
    • Almacenar todo el conocimiento como si de un diccionario se tratase (pero NO en formato códex, sino que tenga la misma información en su propia estructura de datos).
    • Ser capaz de, al principio, asimilar algo de conocimiento con «actos reflejo» como los movimientos espejo.

La gran pregunta es: ¿cómo debe ser una estructura de datos para adaptarse a estas características?

Una teoría que a mi me parece bastante interesante sobre el cerebro humano es la del cerebro triple. Esta teoría dice que el cerebro tiene tres partes bien distinguidas:

  1. El cerebro reptiliano, encargado de actos reflejos.
  2. El sistema límbico, encargado (a grandes trazas) de las emociones y sentimientos.
  3. El neocórtex, la parte racional del cerebro.

Además, parece ser que hay una parte del cerebro dedicada a extraer información de todo lo que captan los sentidos. Por ejemplo, nuestro cerebro está preparado para captar caras en las fotografías, e incluso nos puede llegar a engañar. Esto seria algo así como un preprocesamiento de la información que le llega.

Siempre he pensado que intentando simular un sistema así se podría conseguir una IA real.

Quadcóptero V: Movimientos

Hoy vengo a hablar de la libertad de movimientos en lo que espero que sea la última entrada del blog sobre el quadcóptero antes de poder poner algún avance. De momento, he estado probando a programar PICs (con un programador TE-20 e ICProg en windows). Este es un paso básico para seguir con el proyecto, pero no tiene mayor interés por sí mismo.

El quadcóptero tiene una libertad de movimientos enorme: puede subir/bajar, girar lateralmente, moverse hacia los lados… pero no todos esos movimientos interesan. Por una parte, los movimientos que habrá que manejar serán:

  • Subir/bajar: el más básico de todos, para ganar y perder altura. El acelerómetro nos dirá (gracias a su eje vertical) si el bot sube o baja. Además, es el movimiento más sencillo, ya que basta con regular todos los motores simultáneamente con la misma potencia.
  • Desplazarse lateralmente, hacia la izquierda/derecha o bien hacia delante/detrás. Cuando digo «girar lateralmente» me refiero a avanzar paralelamente al suelo con dos aspas delante y dos aspas detrás. Hay que controlar que el movimiento no sea con un aspa delante de las otras, porque sería más inestable. Para controlar la inclinación se usará el acelerómetro (eje horizontal) o el magnetómetro. Para controlar los motores, habrá que mantener la altura (por tanto, aplicar más potencia a los motores por la inclinación) y para inclinar el bot disminuir la potencia de los dos motores hacia donde nos queramos mover, y aumentar la de los otros dos.
  • Girar lateralmente: mediante un movimiento curvo, como si de un coche se tratara. En realidad serán dos movimientos de desplazamiento lateral simultáneos. Ya entraré en más detalles cuando haga falta.

Por otra parte, hay movimientos que no nos interesan en absoluto, y habrá que ir con cuidado para evitarlos:

  • Giro sobre su eje vertical: si los motores no están perfectamente alineados se puede crear un momento de giro que provoque una aceleración  giratoria. Para evitarlo, lo mejor es utilizar dos aspas levógiras y dos aspas dextrógiras (en el sentido de las agujas del reloj o viceversa, respectivamente).
  • Inclinaciones oscilatorias: al estabilizarse, no puedo provocar que se desestabilice hacia el lado contrario… así que hay que estabilizar con una cierta precisión.

Para finalizar, pienso el final del movimiento (por ejemplo, volver a la posición original después del desplazamiento horizontal) debe ser lo más simple posible. Por tanto, dejaré que el bot entre en estabilización automática (que deberá ser el primer movimiento que se implemente), sin preocuparme de nada más.

Inteligencia artificial I: Sobre el punto de vista

La inteligencia artificial (IA) se podría definir como una rama de la ciencia que se dedica a crear máquinas que se parezcan a los humanos tanto como sea posible. Es bastante popular, ya que a todos nos suena el término de inteligencia artificial, aunque sea por alguna película. Además, es un tema con un desarrollo importante, ya que la meta de la inteligencia artificial es un mundo mucho más cómodo que el que conocemos hoy en día: robots que limpien, cocinen, nos guíen por ferias o grandes superfícies, nos den información detallada y precisa, etc.

Me gustaría hablar del planteamiento que a mi entender se le está dando a la inteligencia artificial actualmente. A día de hoy, nadie ha sido capaz de crear un sistema con un autoaprendizaje eficaz sobre su entorno. Es cierto que se han creado estructuras de datos que permiten aprender de sucesos pasados para mejorar su comportamiento, como son las redes neuronales (que son capaces de aproximar suficientemente bien cualquier función contínua, por ejemplo). No obstante, sólo aproximan una función. No pueden aprender palabras, conceptos o ideas.

Yo, personalmente, pienso que el cerebro es una máquina. Muy potente, muy veloz, muy flexible… pero una máquina, al fin y al cabo. Es más, pienso que se debe poder simular a un humano cualquiera con tanta precisión como se quiera. Por tanto, no entiendo por qué si un humano es capaz de comprender ideas, el aprendizaje en la IA se basa en aproximar funciones o en resolver problemas de decisión básicos (máximos y mínimos de funciones, etc). Es evidente que el objetivo fundamental de la IA es interactuar con el entorno.

Entonces, ¿por qué intentamos resolver con exactitud un problema de millones de variables (computacionalmente imposible), y no buscamos un modelo de aprendizaje más humano?, ¿por qué si intentamos imitar a un humano no intentamos imitar su manera de pensar? Puede que la clave sea olvidar cosas, para así poder aprender otras. Puede que la clave sea saber encontrar qué parámetros son los fundamentales. Puede que la clave sea observar las sitaciones desde una perspectiva más amplia… pero si queremos que un robot coja un vaso de la mesa, seguro que no lo conseguiremos intentando programar qué movimientos debe hacer para cada caso (si el vaso está boca abajo en una mesa, si está boca arriba en una silla, si está en el suelo, si está en el suelo un poco más allá…).

La inteligencia artificial es una ciencia en la que queda mucho camino por delante. Existe una prueba que mide el avance tecnológico en inteligencia artificial: el test de Turing. Consiste simplemente en crear una conversación de unos 5 minutos entre un humano y una máquina preparada para simular a un humano. Si la máquina consigue engañar al humano y que él crea que habla con otro humano, entonces ha pasado el test.

Una prueba del interés en el desarrollo de esta rama de la ciencia es la existencia de numerosos concursos (con premios nada despreciables) en los que el objetivo está relacionado con la IA, como crear un programa que pase el test de turing (Loebner Prize). De momento, este premio sigue desierto. También existen otros concursos relacionados con la IA, como la RoboCup, la RoboCup @home o el Hutter Prize (relacionado con la teoría de la compresión de conocimiento humano).

 

Quadcóptero IV: Estabalidad

La función primordial del quadcóptero es que vuele. Y para eso, evidentemente, necesita una estabalidad muy precisa. Para ello, contará con dos elementos clave: un acelerómetro y un magnetómetro.

El acelerómetro es un dispositivo que nos informa de la aceleración que sufre el bot (fuerza externa aplicada sobre el acelerómetro) y el magnetómetro indica cual es la intensidad del campo magnético que recibe. Tanto el acelerómetro como el magnetómetro separan la información recibida por cada uno de los 3 ejes.

Esta información nos ayudará básicamente a saber hacia dónde nos vamos a mover (acelerómetro) y hacia dónde estamos orientados (magnetómetro).

La idea es utilizar esta información para equilibrar los motores y conseguir que los movimientos sean suaves… pero no es tan sencillo como parece, ya que el quadcóptero tiene que poder moverse lateralmente, y esto implica que se pueda ladear y sigua siendo estable. Para ello, habrá que utilizar algún tipo de filtro adaptativo… pero para esto aún queda mucho por hacer.

De momento tiene que quedar claro que el módulo dedicado a la estabilización tiene que comunicarse con el módulo central e indicarle la posición y la velocidad angular, entre otras cosas, para que éste decida qué decisiones tomar.

También he estado pensando en compartir recursos entre distintos módulos: puede que no sea necesario poner un PIC para controlar el acelerómetro y el magnetómetro, y otro para tomar las decisiones en cuanto a los motores. Mientras la diferencia a nivel de software quede clara, no habrá ningún problema.

Todo esto son planes y más planes sobre cómo creo que saldrá… pero espero ponerme pronto manos a la obra a trastear con cosillas.

El juego de la vida

El juego de la vida no es un juego. Propiamente dicho, es una secuencia de patrones en un tablero bidimensional cuadriculado, así que a primera vista tampoco se diría que tiene algo que ver con la vida.

El juego de la vida consiste en lo siguiente: para empezar, seleccionas un conjunto de cuadraditos de tu tablero, a los que llamaremos células vivas (y los colorearemos de negro); el resto serán células muertas. A partir de ahora, en el siguiente turno una célula se mantendrá viva si tiene 2 ó 3 vecinos; en caso contrario morirá. Además, si una célula muerta tiene 3 vecinos nacerá, convirtiéndose así en una célula viva.

Un ejemplo de juego de la vida en el que se puede comprobar el funcionamiento de las reglas es el siguiente:

En el juego de la vida se han encontrado muchos patrones con curiosas propiedades. El ejemplo de arriba se llama oscilador, ya que cada dos turnos vuelve a la misma posición. Existen osciladores con un período más grande.

Otro ejemplo de patrones interesantes son los planeadores: figuras que se desplazan en el espacio manteniendo su forma.

Éste es el ejemplo más sencillo pero hay otros. Y así como se pueden crear planeadores, también se pueden crear pistolas de planeadores, como el siguiente patrón:

Estos son algunos ejemplos manejables y representativos de lo que se puede hacer con el juego de la vida. El parecido que tiene (o puede tener) con la vida es que a partir de unas reglas muy sencillas, se pueden organizar grandes estructuras que sean poco previsibles. Pero todo esto va más allá: se ha demostrado que se pueden «programar» puertas lógicas (AND, OR, etc.) y contadores. Con esto, se puede construir una máquina de turing (más o menos, el modelo matemático de un ordenador normal y corriente). Esto implica que se podría programar el juego de la vida dentro del juego de la vida… y suma y sigue.

Uno mismo puede probar en este applet, o bien descargarse software optimizado y con multitud de patrones y variantes desde aqui.

Todas las imágenes han sido tomadas de la wikipedia.

 

Quadcóptero III: Modularidad

Para conseguir que el quadcóptero vaya avanzando y no sea uno de los muchos proyectos que se quedan en una idea, creo que es básico empezar a ver progresos desde el primer día. Por ello me gustaría crearlo de la forma más modular posible. Esto es, haciendo que cada funcionalidad sea cubierta por un dispositivo diferente, de manera que todos ellos puedan funcionar por separado.

Un buen ejemplo de esto sería la radiocomunicación: tener un circuito separado que sea capaz de comunicarse con el controlador principal para enviarle las órdenes necesarias. Esto permitiría conectarlo mediante un cable para las primeras pruebas y, una vez que se haya diseñado y probado el módulo de radiocomunicaciones, añadirlo sin necesidad de cambiar nada más.

Esta «filosofía» implica que:

  • Los fallos serán fallos de un módulo concreto, no de todo el bot. Por tanto, no hará falta rediseñar o reprogramar el conjunto, sino tan sólo el módulo afectado.
  • La flexibilidad es mucho mayor. Si en un momento dado se le quiere añadir una nueva funcionalidad, se le añade sin ningún problema. Y si lo que se quiere es modificarla, también se hace sin necesidad de cambiarlo todo.
  • Deben estar bien definidas las funciones del bot (volar, comunicarse con el exterior, estabilizarse, etc) y, sobretodo, deben estar muy claras las relaciones entre los módulos (qué señal envía el módulo de comunicaciones para indicar que hay que volar más alto, por ejemplo).
  • La cantidad de elementos del bot aumenta. En vez de utilizar un sólo circuito para varias tareas, utilizaremos circuitos distintos. Esto implica, entre otras cosas, que el precio y el peso aumentan.

Para empezar, hay varias funciones que son totalmente imprescindibles. Por tanto, hay varios módulos que no deben faltar en cualquier diseño. Estos son:

  1. El cerebro. El módulo central que sea capaz de dirigir a las demás partes. Debe tener la función de decidir cómo se deben mover los motores en función del resto de parámetros (órdenes que le lleguen desde fuera y estabilización del quadcóptero).
  2. La orientación y estabilización. Debe haber un módulo capaz de saber hacia dónde está orientado el bot y hacia dónde está inclinado. Necesariamente debe disponer de un acelerómetro y de un magnetómetro o giróscopo.
  3. Las comunicaciones. Debe ser capaz de hacer llegar al bot la información exterior.
  4. El control de motores. En caso de que los motores deban ser controlados por circuitería electrónica (como éstos) no debe ser necesariamente el módulo central el que se encargue de ello.

En un primer diseño, el módulo de comunicaciones será sustituido simplemente por un cable. El primero en ser desarrollado será el control de motores, que es el más sencillo. Más tarde ya diseñaré el de orientación y estabilización, que tiene más complicaciones pero que hace que el bot sea capaz de volar de manera autónoma. En último lugar, me ocuparé del módulo de comunicaciones. Obviamente, a medida que se añadan más funciones, el módulo principal deberá irse actualizando para ajustarse a ellos.

 

Poker: analizador de manos IV

El analizador de manos parece que funciona bien. Con los archivos auxiliares (las tablas), que tienen que estar en la misma carpeta que el .jar (o en la carpeta del proyecto si se utiliza un IDE), es capaz de calcular manos a una velocidad bastante alta.

Con un procesador de 2.4GHz Intel Core 2 Duo, he ejecutado el código de ejemplo, que recorre todas las posibles manos de la baraja y calcula cuántas hay de cada tipo. La salida del programa ha sido:

Resultados:
Esc Color: 41584
Poker: 224848
Full: 3473184
Color: 4047644
Escalera: 6180020
Trio: 6461620
Dobles parejas: 31433400
Pareja: 58627800
Carta alta: 23294460

Totales: 133784560

Comprobando con la wikipedia la cantidad de manos distintas que hay según el tipo de mano, he llegado a la conclusión de que el funcionamiento parece correcto, ya que coincide en todos los casos.

La ejecución del programa ha tardado 31 segundos, lo cual son 4.300.000 manos/segundo aproximadamente… no está nada mal. Además, en esos 31 segundos el programa inicializa variables y instancias de clases, maneja la baraja, guarda los valores, etc. Ejecutando las mismas sentencias, pero esta vez sin evaluar las manos he comprobado que el tiempo que se tarda en realizar todo este trabajo «extra» es de entre 2 y 3 segundos.

Para finalizar, me gustaría comentar que si bien son unos buenos resultados, no son los mejores. El mismo programa implementado en C++ estaría más optimizado. Además, se han conseguido evaluadores sensiblemente más rápidos.

No obstante, creo que los puntos fuertes de este analizador es que está escrito en Java, y considero que es muy fácil extender este programa o crear nuevas funcionalidades. Además, 4.300.000 manos/segundo es un valor bastante alto, y rara vez necesitaremos una velocidad de cálculo mayor. Lo repito: no creo que sea el mejor, ni tampoco está basado en una idea original, pero es cómodo y se puede manejar fácilmente.

Si necesitas ayuda para hacerlo funcionar, te ha sido de utilidad, lo has modificado o lo has utilizado para cualquier cosa, estaría encantado de que me lo comentaras vía e-mail!

Editado. Puedes descargar los archivos haciendo click aqui:

Analizador de manos de póker (Java)
466.0 KiB
822 Downloads
Details

Poker: analizador de manos III

Una vez que ya está claro cómo va a ser exactamente el analizador, nos podemos poner manos a la obra. A mi personalmente me gusta programar en Java, porque creo que es fácil crear grandes proyectos poco a poco, ya que la estructura de programación ayuda (clases, herencia, etc.). También utilizo NetBeans.

El algoritmo completo podría resumirse así:

  1. La entrada son 7 cartas, cada una con un número y color determinado.
  2. Cada número tiene asignado un valor, y cada color tiene asignado otro valor (según las tablas de las entradas precedentes).
  3. Sumamos los valores de todos los números, y buscamos en la primera tabla el valor de la mano asociado (entre 1 y 7462).
  4. Sumamos los valores de todos los colores, y buscamos en la segunda tabla si hay o no color.
  5. Si no hay color, devolvemos el valor de la mano encontrado en el paso 3.
  6. Si hay color, sumamos todos los valores de las cartas con el palo determinado.
  7. Buscamos en la tercera tabla el valor de la mano teniendo en cuenta el color.
  8. Devolvemos el menos de los dos valores, el del paso 3 y el del paso 7 (ya que la mejor mano es la 1, y la peor la 7462).

Notemos que el hecho de tener en cuenta el color nos ha complicado bastante el algoritmo, pero dado que este es un caso poco habitual (aproximadamente un 0.19% de las manos) no influirá excesivamente en el rendimiento global.

La construcción de las tablas es mecánica y sin demasiado interés. En principio, no postearé el código utilizado ni haré más comentarios al respecto.

Lo único que falta es pasar el algoritmo a código y comprobar su correcto funcionamiento. Para ello, he creado unas cuantas clases en Java que implementen el algoritmo y que sean fácilmente interpretables. En Descargas podéis encontrar los archivos .java, las tablas utilizadas y un léeme para saber cómo utilizarlo. Si queréis utilizarlo para fines personales y/o modificarlo sóis libres de hacerlo, siempre que se respete la licencia GPL. En cualquier caso, si te ha resultado útil o lo has modificado de alguna manera te agradecería que me escribieras porque probablemente me intereserá!

Editado. También te puedes descargar los archivos directamente desde aqui:

Analizador de manos de póker (Java)
466.0 KiB
822 Downloads
Details

Quadcóptero II: Radiofrecuencia y espectro frecuencial

 

Un aspecto clave (y complicado) del quadcóptero es la comunicación remota. Que se pueda controlar a distancia, vamos. Para ello hay varias alternativas (por radio, por infrarrojos, con cable… y seguro que alguna más habrá). No obstante, sin duda alguna la mejor opción es via radio. Para ello, necesitaremos un transmisor (mando a distancia) y un receptor (un circuito en el quadcóptero), que se encarguen de:

  • Codificar/Decodificar: crear un cadena de bits diferente por cada «estímulo» que se quiera enviar.
  • Modular/Demodular: asignar a cada bit o conjunto de bits una señal eléctrica que será lo que se envie.
  • Enviar/Recibir el señal modulado a través del canal (el aire en nuestro caso).

Mi idea inicial es:

  • Para codificar, dado que se enviarán pocos estímulos (subir, bajar, adelante, atrás, izquierda, derecha y poco más), enviar un «1» lógico seguido de un numero variable de «0» lógicos. Así se «desperdicia» mucho potencial, pero se evitan errores de sincronismo y el proceso de codificación se simplifica todo lo posible.
  • Para modular, utilizar lo más sencillo posible: la modulación ASK. La idea es enviar un pulso senoidal cuando hay un «1» lógico, y no enviar nada cuando tenemos un «0» lógico:

Modulación ASK

Uno de los factores más críticos es el espectro frecuencial utilizado (es decir, a qué frecuencia enviaremos el coseno). La frecuencia a la que emitiremos es importante porque sería recomendable utilizar una frecuencia poco utilizada para evitar interferencias. Además, el espectro está muy regulado (es ilegal emitir pulsos electromagnéticos a la frecuencia que quieras).

Existen una serie de bandas reservadas para los radioaficionados que «escapan» a la regulación. Son estrechos intervalos en los que se puede escuchar y emitir (con baja potencia) libremente. Suelen ser bandas bastante saturadas (como la banda ciudadana), precisamente por la libertad de emisión, pero utilizar una de estas bandas me parece la mejor opción.

La banda que me parece más adecuada es la banda de 70 cm. Tiene varias ventajas sobre las otras:

  • Es una banda no tan saturada como la banda ciudadana.
  • La frecuencia va de 420 Mhz a 450 Mhz. Es una frecuencia en la que no es crítico el diseño del circuito, pero no está lejos del límite (a muy altas frecuencias, la colocación de los elementos en las placas y el recorrido de las propias pistas introducen pérdidas y capacitancias parásitas que se tienen que tener en cuenta).
  • La longitud de onda es de unos 70 cm. en el aire. Esto hace que las dimensiones de una antena sencilla para el emisor y el transmisor (como es el dipolo) sean manejables: unos 35 cm. (la mitad de la longitud de onda). Notemos que si utilizásemos la banda ciudadana, en los 27 Mhz, la longitud de onda sería de 10 metros.

Dentro de cada banda existe una distribución de las frecuencias en función del uso que se le da. Estas directrices (que son recomendaciones, pero no obligaciones) son conocidas como el plan de bandas. En el caso de la banda de 70 cm., creo que una buena opción seria utilizar una frecuencia comprendida entre los 433.625 Mhz y los 433.775 Mhz:

Plan de Bandas

Ya volveremos sobre estos temas más adelante, durante el diseño de los circuitos del transmisor y el receptor, porque de momento sólo estoy planificando cómo sería la mejor manera de realizarlo. Los parámetros finales (modulación, frecuencias utilizadas, etc.) dependerán de las dificultades en la implementación y probablemente variará en función de las nuevas ideas que vayan surgiendo.

 

Lineups.net: CSS

Hace poco hemos estrenado un nuevo diseño en la página web Lineups.net. Anteriormente teníamos un diseño provisional, que permitía mostrar información en forma de tablas. Era simplemente un fondo blanco con 3 columnas, sin ningún colorido ni atractivo visual. El nuevo diseño es simplemente una reestructuración de los contenidos, añadiendo color y formato al texto.

El diseño no lo he creado yo, sino que mi trabajo ha sido pasar el diseño a HTML, PHP y sobretodo, a CSS. El CSS es un archivo que «explica» cual es el formato visual de los elementos. Se basa en el modelo de cajas: se describen las diferentes «cajas» que aparecerán en la página web (una para el título, otra para el encabezado, una para la columna izquierda, etc.). Se puede personalizar una gran cantidad de parámetros (posición, alineamiento del texto, color de fondo, etc.), y se pueden anidar.

Es la segunda vez que utilizaba CSS un poco en serio… y la verdad es que estoy ampliamente decepcionado. A primera vista parece que el CSS es el complemento perfecto al HTML para dar formato a las páginas web (ya que las etiquetas html son limitadas), pero una vez que te pones a maquetar es frustrante. Es un lenguaje lleno de propiedades que tienen varios significados, según el contexto (un ejemplo: la propiedad «left: 10px» puede o no tener sentido, según qué valor tome la propiedad «position»). Tiene alguna incoherencia (si utilizas la propiedad «float:left» en una caja, su caja contenedora no se adapta a su tamaño automáticamente, sino que necesita una propiedad que se lo indique, «overflow: hidden»), etc.

Además, la implementación del lenguaje no se ha completado hasta hace poco en Internet Explorer (se ve que antes de la versión 8 era terrible), y hay propiedades en las que hay que adaptarse a cada navegador (como la de redondear las esquinas, que necesita una etiqueta por navegador).

La verdad es que el hecho de que vaya por la tercera versión deja entrever que nunca será un lenguaje realmente potente, escalable y reutilizable, lo que deja la maquetación de páginas web sin ninguna buena opción.