Posts filed under 'Programación'
Como sabéis los mas asiduos, he pasado los 3 últimos meses intentando crear un vídeo RLV para el rodillo Fortius. En mi ultimo post, afinando aún mas los RLV, parecía que por fin había conseguido mi propósito, pero no. Debido a un incompleto entendimiento de uno de los conceptos fundamentales de los RLV, mis vídeos nunca estaban bien sincronizados con el perfil de la etapa.
El concepto en cuestión es el de “distance per frame“. Los archivos RLV tienen unos registros que se llaman así. Se componen de un número de frame y un valor que indica la distancia que es necesario recorrer con el rodillo a esa altura del vídeo para que se pase al siguiente frame.
Este dato se calcula a partir de la velocidad a la que nos movíamos mientras se grabó el vídeo y su tasa de frames por segundo, por ejemplo, si he grabado un tramo a 50Km/h, que son 13,8m/s y el video fue grabado a 25fps, en ese tramo el valor de distancia por frame será de 13,8 / 25 = 0,555 metros por frame.
Me he pasado semanas haciendo números, porque yo entendía que desde un registro hasta el siguiente el valor de distancia por frame se mantenía constante… y ademas no se me ocurría ninguna otra posibilidad.
Pregunté por el tema a Phil, el que hace los videos oficiales, y no obtuve ninguna respuesta (no les hace gracia que la gente haga sus propios vídeos). Pregunté a B. Maesen (Wesp_im), el que hace las camisetas oficiales del VR y aunque el no sabía nada, me puso en contacto con Hannes Schellnast, un Austriaco que ha hecho un par de vídeos a mano, usando una variante del sistema de hojas de cálculo de Carsten Jost.
El ha sido quien, después de investigar un poco se ha dado cuenta de una cosa muy importante. Desde un registro de distance per frame a otro, el valor de distancia NO se mantiene constante, sino que se interpola desde el valor de origen hasta el de fin. Una vez entendido esto, ya he podido corregir mi conversor para que saque unos valores de distance per frame adecuados.
| Frame number |
Distance per Frame |
| 0 |
0,5 |
| 1 |
0,5 |
| 8 |
1 |
| 9 |
1 |
|
Esto es lo que yo pensaba que ocurría:
|
Y esto lo que ocurría en realidad:
|
|
Como se ve, el valor de distancia por frame varía de forma lineal en el intervalo que no está definida, es decir, entre el frame 2 y el 7. Esto explica todos los comportamientos anómalos que obtenía en mis pruebas ya que en cuanto creaba un registro nuevo, mis valores estimados de velocidad no coincidían con los que al final calculaba el software de Fortius y todo se desfasaba.
En palabras del propio Hannes: “Teóricamente la distancia cubierta se calcularía vía una integral desde el frame 1 hasta el 9. En nuestro caso hemos interpolado valores discretos para los puntos de distancia por frame. Esto significa que no usaremos integración gracias a que los saltos entre frames son discretos y no infinitesimales. Supongo que el algoritmo que usa Tacx calcula la nueva distancia cubierta para cada paso de frame al siguiente con el valor de distancia por frame interpolado. Hay que tener en cuenta que la dependencia entre frames y distancia cubierta no será lineal para el rango de frames entre el 1 y el 9. Debido al uso de valores de frame discretos se produce un pequeño error de cuantización respecto al valor que saldría con un cálculo teórico basado en integrales. Este error es tan pequeño que se puede despreciar.”

Ahora ya comprendido el funcionamiento he cambiado la generación de los .rlv y parece que todo coincide, casi a la perfección. A Hannes le debo una y probablemente le envie un regalito, ¿alguna sugerencia de algo que enviarle que no se rompa de aqui a Austria?
febrero 4th, 2009
Después de hacer pruebas con el programita que me hice y que comenté en el anterior post me he dado cuenta de que hay aún problemas para empatar correctamente las pendientes con las imágenes del vídeo.
Si antes el problema lo presentaba el mapeo entre pendientes y distancias, ahora el problema está entre distancias y velocidades de grabación del vídeo. En efecto, la pésima grabación que hice del track no solo afectó a las alturas mal calculadas, también hacía que las velocidades fuesen distintas a las que se reflejan en el vídeo.
Esto hace que al reproducir el RLV en su entorno propio, el software de Tacx, al cabo de unos kilómetros la posición que reflejaba el vídeo, por ejemplo en la entrada de una población, no correspondía con la distancia recorrida que marcaba el track y por eso las pendientes tampoco se correspondían.
El mejor método que se me ocurrió para arreglar esto de una vez por todas es el de usar un mapa de google sobre el cual se dibuja el recorrido y sobre el que se va actualizando la posición real. En este mapa podría ir marcando puntos a medida que se reproduce el vídeo para empatar momentos de tiempo (frames de video) con posiciones GPS y de esa forma consigo exactamente la velocidad entre los puntos que vaya marcando. Por ejemplo, cuando veo en el vídeo una curva a derechas, busco en el mapa de google si la posición actual que me marca en el mapa corresponde con el inicio de dicha curva y si no es así, lo que hago es colocar un marcador que indica donde debería estar (dentro de la propia linea del track) y el programa recalcula las velocidades para todo el recorrido. De este modo, colocando unos cuantos marcadores, se consigue cuadrar a la perfección el vídeo con el track GPS y la corrección que se haga después sobre el perfil quedará perfectamente sincronizada con el vídeo en el software de Tacx.
Para esto he usado el API de Google Maps para Flash. Tardé aproximadamente 30 minutos en poner el mapa, dibujar el recorrido y centrar el mapa en punto de latitud y longitud correspondiente a medida que se reproducía el vídeo, es muy fácil de usar.
En seguida se hicieron evidentes las diferencias entre la reproducción del vídeo y las posiciones en el mapa.
Hacer la funcionalidad para recalcular los tiempos y las velocidades me llevó alguna que otra semana, pero al final todo salió.

En la captura de pantalla se puede ver en azul los marcadores utilizados a lo largo del recorrido para empatar vídeo y latitud-longitud. Hay tramos en los que la velocidad es mas constante y hay menos marcadores y otros tramos en los que hay que colocar mas.
Los marcadores se colocan haciendo click en el punto del track que queramos y también se pueden eliminar si nos hemos equivocado al colocarlos simplemente clickando encima de su icono.
El resto del mapa funciona igual que cualquier otro mapa de google maps, con la salvedad de que en ocasiones al usar el zoom el programa da un error de seguridad (pero no siempre). Supongo que es un problema por usar AIR en vez de simplemente Flash ya que hace poco que el API de Gmaps soporta AIR.
Soy consciente de que es probable que no esté quedando nada claro lo que hago ni porqué lo hago, pero el explicarlo aquí no solo me permite documentarlo un poco sino también organizar mis ideas y conclusiones respecto a este tema. La verdad es que todo esto me resulta muy difícil de explicar porque el problema es bastante complejo de entender si no te has metido a resolverlo, pero lo importante es que voy a tener una herramienta fiable para producir casi en serie los vídeos RLV que quiera. De hecho con este nuevo añadido voy a poder incluso hacer RLV sin disponer del track GPS ya que me bastaría dibujarlo sobre un mapa, calcularle las alturas, ponerle una velocidad constante y luego ir ajustando visualmente con mi mapa las coincidencias entre fotogramas y posiciones geográficas.
Me imagino que en Tacx tendrán una herramienta similar, porque no me imagino a Phil, el encargado de hacer los RLV comerciales, corrigiendo a mano sobre una hoja de cálculo las cifras de pendientes tal y como hace Carsten Jost en su guía de creación de RLV.
… y si no la tienen, siempre estoy dispuesto a trabajar para alguien que conjugue bicicletas + informática
(Creo que esta última frase solo tendría sentido si postease en Inglés como mi colega futur3, pero me da tanta pereza…)
enero 12th, 2009
Para cocinar un RLV de Tacx se necesita como materia prima los siguientes ingredientes:
- Un vídeo de un recorrido en carretera o camino, grabado a una velocidad que no supere en mas de 20Km/h la velocidad que llevaría un ciclista normal en ese tramo
- Una grabación simultanea del track GPS del recorrido.
Como los GPS tienden a perder señal de vez en cuando y se vuelven un poco erráticos, siempre hay que hacer una labor de limpieza antes de poder pasar a usar el track obtenido.
Se trata de ajustar el archivo GPX obtenido del GPS eliminando puntos parados y sobrantes al inicio y final y puntos aberrantes a lo largo del recorrido. Usando CompeGPS sobre un mapa de google puedes darte cuenta cuando el track se ha desviado del recorrido e intentar retocar esos puntos para que cuadren lo mas posible.
Un indicador muy sencillo es pedirle al Compe la lista de puntos poniendo una columna con la velocidad entre ellos. Como los puertos los subo a una velocidad baja, cuando hay perdida de señal suele haber variaciones imposibles de velocidad, como 120 o 200 Km/h. Esos puntos hay que corregirlos ubicandolos de tal modo que la velocidad entre ellos sea la que tiene que ser, o cercana.
También se toman medidas erróneas de altitud y estas son mas difíciles de corregir, ya que los errores suelen acumularse y luego corregirse de golpe, con lo que aparecen escalones de varias decenas de metros en el perfil que serian sencillas de suavizar si no fuera porque lo mas probable es que luego la pendiente obtenida no coincida con lo que estamos viendo en el vídeo.
Cuando el track está ya limpio paso a ejecutar la aplicación de conversión que he creado, que convierte el GPX en un fichero RLV que básicamente contiene las velocidades a las que ha sido grabado cada tramo del video y un PGMF que contiene las pendientes para cada tramo del recorrido. Ambos tramos, el de la velocidad y el de la pendiente, no tienen por qué ser coincidentes.
Aún con estas correcciones, la mayoría de las veces no se consiguen unas pendientes coincidentes con la carretera que estamos viendo en el vídeo. Si suavizas mucho poniendo tramos largos con la misma pendiente, habrá cuestas arriba y abajo que no se reflejen en el rodillo. Si por el contrario haces tramos demasiado cortos, en algunos momentos las pendientes serán ridículamente altas para distancias muy cortas y variarán mucho, por lo que no se consigue un recorrido fluido.
Todo esto es especialmente cierto si, como me ocurrió en las primeras grabaciones, has configurado mal el GPS y has grabado muy pocos puntos. Si el GPS captura un punto del track cada 10 segundos, por ejemplo, a 40 o 50 por hora recorres mas de 100 metros en ese tiempo (50km/h = 11.1m/s) y ahí puedes haberte perdido muchos altibajos del camino. Lo ideal es configurar el GPS para grabar un punto por segundo.
He intentado arreglar el desaguisado resampleando el track con un programa que he descubierto que te permite hacer esto y muchas otras cosas (cosas muy curiosas como redes de caminos a partir de tracks y varias opciones muy interesantes para ciclismo) con los mapas y tracks. El TopoFusion tiene una opción de interpolar mediante splines un track que te permite insertar el número de puntos que quieras entre los puntos de tu track, trazando curvas donde antes había rectas y siguiendo así de manera mas natural lo que podría ser el movimiento real que ha habido entre dos puntos capturados por el GPS.
Aquí se puede ver un ejemplo de track resampleado con splines.
A pesar de que TopoFusion también interpola y splinea las alturas, decidí volver a recalcular automáticamente la altura de los puntos. Esto lo hace el CompeGPS mediante mapas de relieve, pero el TopoFusion también lo hace usando además diferentes métodos (Climbing Analisys) para que elijas el que mas se ajuste a la realidad. Las alturas interpoladas son inventadas y las del mapa de relieve, aunque no tienen mucha resolución, al menos son reales.
El problema es que muchas veces una carretera no se corresponde con la altura media de la zona donde se encuentra, y esto es especialmente cierto para pasos elevados, puentes, túneles, o curvas en herradura, que son bastante habituales, por lo que al final, el resultado del cálculo automático de alturas sigue siendo desastroso e irreal y las pendientes no corresponden con la realidad mas que en unos pocos tramos.

Por eso he tenido que construirme un programita en AS3, usando Air para poder guardar archivos, que sobreimpresiona el perfil de la etapa sobre el vídeo de la misma y permite ir seleccionando tramos para corregir o establecer su pendiente de forma manual, consiguiendo de este modo un resultado mucho mas natural y unas sensaciones mas realistas. A cambio, la programación para sincronizar el vídeo, que funciona por tiempo, con el perfil, que lo hace por distancia, ha sido bastante compleja, pero aquí tenéis un ejemplo de como luce la aplicación. Como es para uso interno, no tiene adornos, que nadie me tache de cutre!!
Le he ido añadiendo lo que necesitaba. Todos los datos sobre la posición actual, distancia, tiempo, pendiente y altitud así como botones para seleccionar tramos (zona en verde), cambiarles la pendiente, o flechas para subir o bajar el perfil y para guardar archivos con el resultado, tanto en un xml de cosecha propia que he llamado “prf” y que es el archivo que lee el programa para comparar el perfil original (en blanco), que se toma de un GPX, con el perfil retocado (en rojo), como en el formato nativo de Tacx pgmf.
Ahora ha producir perfiles como loco para la LEVE!!!
diciembre 28th, 2008
El manejo de vídeo desde Flash es relativamente sencillo. Desde AS3 se utiliza la clase FLVPlayer a la que solo hay que definirle unos pocos parámetros para que enseguida comience a reproducir el vídeo en formato FLV que le especifiquemos.
Esta clase permite entre otras cosas posicionar la cabeza lectora del video en cualquier posición
de tiempo dentro del mismo con una precisión de milisegundos mediante la propiedad playheadTime, que es equivalente al método seek.
He necesitado usar esta propiedad pero me he encontrado una desagradable sorpresa cuando he intentado posicionar la cabeza lectora, por ejemplo, en el segundo 5, el vídeo se iba a la posición 5.75. Siempre.
Después de investigar un rato he llegado a la conclusión de que solo se puede posicionar la cabeza
en frames marcados como keyframes (o I-Frames), por lo que si has encodeado el vídeo con un keyframe cada 12 frames (valor habitual) y el video es a 25fps te encuentras con que solo te puedes posicionar en determinados momentos de tiempo del vídeo, en este caso puedes posicionarte en el segundo 0.48, 0.96, 1.44, 1.92, etc…
El caso es que necesito posicionarme en segundos exactos por lo que no me queda otra solución que encodear el vídeo con una frecuencia diferente, de un keyframe cada 5 o uno cada 25 si no necesito tanta resolución. La primera solución, por supuesto provoca un aumento significativo del tamaño del vídeo, pero en mi caso eso no es ningún problema, solo es algo que hay que tener en cuenta a la hora de preparar los vídeos para la aplicación. La segunda solución empeora la calidad, pero disminuye el tamaño. Como mi caso es para hacer una previsualización, pues tampoco es importante la calidad.
De los encoders de FLV que tengo a mano, el único que me ha dejado elegir el numero de keyframes ha sido el propio Adobe Flash CS3 Video Encoder y despues de esperar un buen rato porque es muy, muy lento, resulta que al principio lo hace bien, pero no es capaz de poner los keyframes EXACTAMENTE cada 25 frames de una manera constante, por lo que a los pocos segundos comienza a desincronizarse con lo que al final me encuentro con el mismo problema. Parece que los keyframes no son una ciencia exacta.
diciembre 5th, 2008
Como ya dije, según fuese aclarando las dudas acerca de detalles de la creación de componentes en Joomla 1.5.6, las iría publicando, así que allá voy con las primeras:
¿Como insertar una definición de hoja de estilo propia desde una vista generada por mi componente?
Pues no es muy elegante, pero asi es como se hace:
// Recuperamos una referencia a la instancia del documento que genera Joomla
$document = & JFactory::getDocument();
// Asociamos una hoja de estilo al documento
$document->addStyleSheet("components/com_mycomp/views/assets/mystylesheet.css");
¿Como hago para que mi módulo aparezca en el Pathway de la página, también llamado modulo BreadCrumb?
Para variar, menos elegante aún que la anterior, usando la palabra clave global que es la antitesis de la ocultación de datos y por tanto de la orientación a objetos, hacemos referencia a una instancia del JAplication que se llama mainframe (¿y como sabemos eso?). Ignoro si hay una forma mas ortodoxa de hacerlo. En una de tus vistas mete este código en el método display:
global $mainframe;
$pw = $mainframe->getPathWay();
$pw->addItem("Mitextoparaelpathway");
¿Por qué no consigo recuperar el modelo desde una de mis vistas?
Lo mas habitual es que se te haya olvidado poner el nombre del modelo en cuestion que necesitas. Si dejas el parámetro del nombre del modelo vacío, la vista tratará de encontrar un modelo con el mismo nombre que ella. La solución es poner el nombre del modelo o crear un modelo con el mismo nombre que la vista.
views/myview/view.html.php
$model = $this->getModel("Mymodel");
models/mymodel.php
defined('_JEXEC') or die();
jimport( 'joomla.application.component.model' );
class MyApplicationModelMymodel extends JModel
{...
o
views/myview/view.html.php
$model = $this->getModel();
models/myview.php
defined('_JEXEC') or die();
jimport( 'joomla.application.component.model' );
class MyApplicationModelMyview extends JModel
{...
octubre 19th, 2008
Llevo varias semanas investigando como hacer componentes para Joomla 1.5.6. Ya he conseguido alguna cosilla, pero no es tan sencillo como en un principio se suponia que iba a ser.
Joomla 1.5.6 usa una arquitectura basada en el patrón MVC (Modelo Vista Controlador), algo que no es nada nuevo en otros lenguajes como Java o Ruby pero que en php no es tan habitual, al ser php históricamente un lenguaje menos formal.
En MVC las aplicaciones tienen 3 partes diferenciadas:
- El modelo: se encarga del manejo de datos, de extraerlos, validarlos y almacenarlos, ya sea en base de datos (lo mas habitual) o en otros medios. Si alguna parte de la aplicación necesita manejar datos, se los pide al modelo.
- El controlador: recibe las peticiones del usuario y las transforma en acciones reales del programa. Habitualmente pidiendo datos al modelo y haciendo operaciones con ellos para después elegir una vista adecuada con la que mostrarlos.
- La vista: se encarga de la visualización de los resultados del proceso que ha tenido lugar en el controlador.
Esta división supone una gran ventaja, y es que cuando necesites ampliar la aplicación es muy sencillo saber que parte debes tocar, que es cada cosa y donde está ubicada. Como contrapartida la complejidad de hacer una aplicación se dispara, la programación orientada a objetos se hace obligatoria y muchos desarrolladores de php amateur quedan fuera de juego.
Con esta aproximación, programar en php no difiere mucho de hacerlo en Java, ya que php orientado a objetos (php 5) tiene una sintaxis muy similar a C++ y por tanto a Java, pero sin las ventajas que este ultimo ofrece en cuanto a tipado fuerte (los tipos de datos hay que declararlos siempre y el compilador da error si se asignan valores u objetos de un tipo incorrecto), por poner un solo ejemplo.
La laxitud en determinados aspectos del lenguaje que presenta PHP era muy buena cuando se trataba de hacer pequeños (o grandes) scripts que funcionaban de manera secuencial, o funcional, pero cuando entran en juego conceptos como la herencia de clases, los interfaces o las clases abstractas PHP te obliga a hacer casting especifico en cada asignación si quieres tener la certeza (mediante un error en tiempo de ejecución, ya que php no se compila) de que estas asignando una objeto válido, y eso es muchísimo mas trabajo.
Lo que ofrece el framework de Joomla en su implementación del MVC que mejora o al menos aligera el trabajo que tiene programar en entornos similares en Java como Spring o Struts es que Joomla tira mucho de “convención” en lugar de hacerlo de “configuración” como hacen los frameworks Java. En eso se parece mucho mas al RubyOnRails aunque sin llegar al extremo de este ultimo, que es el lenguaje de las convenciones por antonomasia.
Lo bueno de la programación por convención es que te ahorras escribir innumerables ficheros de configuración en los que le indicas al framework que es cada clase, si es parte del modelo, de la vista o del controlador, donde se ubica, etc. ya que automaticamente Joomla espera que las clases que representan cada cosa tengan un nombre concreto que se compone de varias partes. Lo malo es que tienes que saberte esas convenciones, que no son estándares, o si no puedes recordarlas, al menos tener una buena documentación de referencia que las explique, cosa de la que, a mi modo de ver, carece Joomla.
La documentación de Joomla está muy orientada al usuario o administrador del sitio que se crea con el, pero es mas difícil de encontrar buena documentación para el desarrollador que a menudo se ve tirando de tutoriales hechos por terceros, consultando foros recónditos y buceando en el código de los componentes que vienen de serie para poder entender como se hacen determinadas cosas.
Y bueno, despues de este “Rant & Rave” no me queda mas que recomendar un par de tutoriales para aprender lo básico (y solo lo basico) sobre como hacer componentes en Joomla 1.5.6. Soy un poco pesadito con la versión de Joomla porque la anterior, la 1.0, no usa el paradigma MVC y por lo tanto la creación de componentes es completamente diferente.
El primer tutorial está en español y es el de Nosolocodigo de David Noguera. Lo cierto es que es un tutorial muy clarito y desmenuzado, aunque no entra en muchos detalles (lo cual es de agradecer si es el primer tutorial que lees), es sin embargo muy bueno para empezar. Si hay algo que echarle en cara es el ejemplo escogido. El “hola mundo” habría sido una birria, pero llamar “prueba” a tu componente es bastante poco esclarecedor y antieducativo 
Otro tutorial lo he encontrado en el propio wiki de Joomla y consta de 4 partes. Puede parecer que me contradigo pero no, el tutorial está bien (salvo por el hecho de que, si, en efecto, al componente lo han llamado “Hello”), es un poco mas completo que el de nosolocodigo (de hecho estoy casi seguro de que David se ha basado en este) pero hay cosas que se quedan sin explicar y que no son fáciles de encontrar. Algunas que echo en falta yo: ¿como metes tu aplicación en el menú del administrador? ¿como creas date pickers en tus formularios? ¿como insertas una hoja de estilo propia de tu componente en la vista? Cuando encuentre las respuestas las iré poniendo.
Es poco probable que haga un tutorial, ya que ya existen estos dos, pero lo mismo problemas concretos si que publico.
octubre 10th, 2008
Con el tema del coche nuevo y el reproductor MP3 me he introducido sin querer en otro jardín del que hasta ahora solo había odio hablar de lejos, el de los sistemas de diagnóstico electrónico de los coches modernos.
En mi caso, un Volkswagen, se utiliza un protocolo llamado CAN-BUS (Controller Area Network) de la casa BOSCH para la comunicación entre los diversos elementos electrónicos del coche y para el acceso a todos los datos de diagnóstico del vehículo. Aquí tenéis una introducción al mismo.
Por supuesto, para conectarse al bus y extraer la información se necesita un cable con un conector especial especificado por la norma EOBD (European OnBoard Diagnosis) o la OBDII que es mas moderno.
En un principio los cables estaban dotados de lo que se llama una línea K, la responsable de transmitir los datos. Mas tarde llegaron los K/L, para vehículos en los que hacía falta “despertar” el sistema de diagnóstico, para lo que se usaba la línea L, y por último hasta el 2004 o 2005, antes de que los VAG adoptaran el sistema CAN-BUS, todas las opciones se podían verificar con unos cables llamados Dual K o KKL (doble línea K y una línea L) que se pueden encontrar en Ebay por cantidades irrisorias (sobre los 15 o 20 Euros). A partir de esta fecha la mayoría de los coches solo mantienen por KKL la diagnosis del motor (por compatibilidad), el resto de elementos funcionan ya en CAN-BUS y se necesita un cable especial, que lleva integrada una circuitería distinta y que se denomina HEX-CAN.
Los talleres habitualmente utilizan costosos aparatos de diagnostico multimarca o de una marca concreta si son talleres oficiales, pero los cables de los que hablo, específico para VAG, fueron originalmente diseñados por una empresa llamada Ross-Tech que los popularizó junto con su software VAG-COM.
El cable HEX-CAN usb con el VAG-COM (software) cuesta aproximadamente $350. Los asiáticos, muy
manitas en esto de copiar la electrónica, no han tardado en sacar cables “piratas” que en el caso de los HEX-CAN cuestan alrededor de los 100 Euros… el software lo compras como puedas o utilizas algunas aplicaciones gratuitas que existen.
Lo mas sangrante, sobre todo para los clientes de Ross Tech, es que el software VAG-COM es capaz de detectar que versión de cable tiene el usuario, y si no coincide con la versión del software, el propio software lo “desactiva”, por decirlo de una forma fina (la forma basta es: ¡TE JODE EL CABLE!). Los cables así desactivados no se pueden volver a usar y tienes que adquirir otro. El cable actúa como una “mochila” o “dongle” que dicen los angloparlantes, donde va incrustado el numero de licencia de uso del software.
Para ahondar mas en la herida, el software se actualiza por Internet automáticamente, por lo que si no estás espabilado puede que tu cable se joda automáticamente también, y eso, para algo que te ha costado $350 (o 100 Euros), no mola ni un poquito.
Pero claro, la gente que se exprime mucho el cerebro se ha puesto a hacer una especie de ingeniería inversa hasta que han dado con la solución hace un par de meses. He leído con avidez y por completo un hilo del foro VAG-Club en el que unos españolitos se han currado una guía para volver a la vida a los cables desactivados. Advierto que es bastante complicado y denso de leer el tema si no se tienen nociones de electrónica y de programación de microcontroladores.
El cable lleva un Amtel Atmega162 y una memoria eprom responsable de la detección del USB que hay que reflashear para que el cable vuelva a la vida.
De paso han conseguido el firmware del Atmega para la versión de cable compatible con la versión 704.1 del software, que es la última, y con ello pueden hacer el “upgrade” a cualquier cable HEX de versiones anteriores, aunque lo mas probable es que a nadie se le ocurra montar todo el tinglado que hay que montar si su cable funciona correctamente, simplemente para actualizarse.
Para hacerse una idea de todos los cambios que pueden realizarse sobre un vehículo con esta herramienta merece la pena darse una vuelta por el foro de VAGClub dedicado a la diagnosis electrónica.
Por si en algún momento desaparecen los archivos del foro de vagclub, aqui os los dejo:
abril 29th, 2008
Por fin me pongo en marcha con este proyecto tan completito y a la vez tan inútil que llevo meses intentando empezar.
Voy a fabricarme un anemómetro digital casero con la sana intención de medir el viento reinante en la zona donde vivo y sopesar si merece la pena montarme un generador eólico de “pinipon“, que por supuesto también estaría amparado bajo la filosofía del HUM.

Mi primera idea era la que suele aparecer en todos los sitios en los que te explican como construir un anemómetro casero de cazoletas. Al conjunto rotatorio que forman las 3 cazoletas con el rodamiento se le incorpora un imán que al pasar por el sensor de efecto hall cierra un circuito que permite contabilizar una vuelta. Si calculas las vueltas por segundo ya tienes una medida de velocidad base que comparar con la velocidad del viento.
Es algo relativamente sencillo pero tiene un problema. No mide la dirección del viento. Se necesita una veleta adicional para medirlo.

Para construir una veleta también había varias opciones, las mas simples con 8 sensores magnéticos como el comentado antes te permitían saber -mas o menos- la dirección del viento de entre 8 posibilidades. Bastante patético.
Sin embargo la aproximación mas directa era la del potenciómetro. Un potenciómetro rotativo al que se le incorporaba la veleta, va quedando siempre en una posición determinada dependiendo de la dirección en que sopla el viento. Para cada posición la resistencia ofrecida por el potenciómetro es distinta por lo que mediante un simple conversor analógico digital de resolución suficiente podemos obtener un amplio abanico de valores que nos indiquen la dirección exacta del viento.
Desde luego parece la mejor solución si no fuera porque los potenciómetros normales que existen en el mercado no superan en el mejor de los casos los 270º de giro, por lo que siempre quedaría una zona muerta de 90º en la que no podríamos medir el viento.
Por supuesto hay potenciómetros de 360º, incluso los hay sin tope para que puedan girar locos, pero su precio en España es mayor que el de un kit de veleta completo comprado en USA, y yo, además de pasarlo bien haciendo inventos, espero también que no me arruine con ellos.
Seguí investigando y leyendo sobre el tema hasta que di con un curioso invento: un anemómetro que combina en el mismo aparato la captación de la velocidad y dirección del viento. Se llama Rotorvane Anemometer y hasta hace unos años vendían un kit para hacértelo tu mismo. Ahora RayMarine les ha comprado la patente y ya no se puede ver libremente que tecnología usan, aunque explican a grandes rasgos como funciona el invento.

Se trata de un anemómetro de cazoletas tradicional en el que una de sus cazoletas tiene una asimetría aerodinámica con respecto a las otras dos. Esto hace que a una velocidad de viento constante, la velocidad angular del conjunto varíe en determinado momento de cada giro dependiendo de por donde sopla el viento. Es decir, existe una diferencia entre la velocidad media del conjunto y la velocidad instantánea en algún punto de cada giro. Si sabes en que punto del giro se produce esa diferencia, sabes de donde viene el viento. Enrevesado, pero muy inteligente.
Afortunadamente el mundo esta lleno de frikis y James Derrick, que hizo el proyecto en 1999 (no ha llovido ni na), lo documentó de manera escueta, lo que me permite entender un poco mejor cuales son los pasos a seguir.
Lo que se me ocurrió a continuación fue fantástico y constata que tengo algún tipo de fijación con los ratones de ordenador. El principio por el que funcionan los ratones de bola es que un disco con perforaciones pasa por delante de un puente óptico que al ser interrumpido se interpreta como movimiento. Un ratón es capaz de dar distancia recorrida en 2 ejes mediante este principio y ademas el sistema es circular, así que me bastaría acoplar un disco perforado y engancharlo al sensor óptico de un ratón para que la circuitería del mismo me fuese diciendo el movimiento que realiza el rotor del anemómetro. La información me llegaría por el puerto PS/2 y un programa podría calcular la velocidad a partir de esos datos.

Así que me puse manos a la obra para hacer alguna pequeña prueba. Desmonté el ratón, enganché la rueda dentada al rodamiento y la uní a un pequeño motor de DC mediante una goma de transmisión, conecté el motor a la línea de 5V de mi fuente de alimentación de pruebas intercalando un potenciómetro para controlar la velocidad de giro y conecté el cable al puerto PS/2 de mi servidor Linux.
En el servidor hice un pequeño programa en C que abre el /dev/psaux y se pone a leer de el. Ayudandome de la información que encontré en la página de Computer-Engineering he podido configurar el ratón para que actúe a la máxima capacidad de muestreo (200 muestras por segundo) y máxima resolución (8 counts por mm) y me ha permitido saber para que sirven cada uno de los 4 bytes que envía el ratón en cada muestreo. El programa acumula todos los movimientos que le llegan del eje Y y va calculando la velocidad media cada segundo.
#include
#include
#define TRUE 1
#define FALSE 0
int main (int argc, char *argv[])
{
FILE *pfile;
char data[4];
int end=FALSE;
long acumulado=0L;
struct timeval starttime, endtime, diff;
long elapsed, totaltime=0;
double velocidad, vmax=0;
pfile = fopen("/dev/psaux", "r+");
// Set sampling rate a 200
fputc(0xF2, pfile);
printf("Preguntando por el device id, respuesta: 0x%x 0x%x\n", fgetc(pfile), fgetc(pfile));
fputc(0xF3, pfile);
printf("Cambiando el sample rate, respuesta: 0x%x\n", fgetc(pfile));
fputc(200, pfile);
printf("Cambiado el sample rate a 200, respuesta: 0x%x\n", fgetc(pfile));
fputc(0xE8, pfile);
printf("Cambiando la resolucion, respuesta: 0x%x\n", fgetc(pfile));
fputc(0x03, pfile);
printf("Resolucion, a 8count/mm respuesta: 0x%x\n", fgetc(pfile));
gettimeofday(&starttime, NULL);
elapsed = 0;
while(! end)
{
data[0] = fgetc(pfile); // Info de los botones y desbordamientos
data[1] = fgetc(pfile); // Incrementos del eje X
data[2] = fgetc(pfile); // Incrementos del eje Y
data[3] = fgetc(pfile); // Incrementos del eje Z (wheel)
acumulado += data[2];
gettimeofday(&endtime, NULL);
timeval_subtract(&diff, &endtime, &starttime);
elapsed += diff.tv_usec;
starttime = endtime;
if(elapsed>=1000000)
{
velocidad = (double)acumulado / (double)elapsed;
if (vmax < velocidad ) vmax = velocidad;
totaltime +=elapsed;
elapsed = 0;
acumulado = 0;
printf("Velocidad = %f t/s Max:%f t/s Tiempo de medicion: %f s\n", velocidad*1000000, vmax*1000000, (float)(totaltime / 1000000));
printf(" = %f km/h \n", velocidad * 1000000 * 9 * 0.0174 * 0.8 * 3600 / 100000 );
}
}
fclose(pfile);
}
/* Subtract the `struct timeval' values X and Y,
storing the result in RESULT.
Return 1 if the difference is negative, otherwise 0. */
int
timeval_subtract (result, x, y)
struct timeval *result, *x, *y;
{
/* Perform the carry for the later subtraction by updating y. */
if (x->tv_usec < y->tv_usec) {
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
y->tv_usec -= 1000000 * nsec;
y->tv_sec += nsec;
}
if (x->tv_usec - y->tv_usec > 1000000) {
int nsec = (x->tv_usec - y->tv_usec) / 1000000;
y->tv_usec += 1000000 * nsec;
y->tv_sec -= nsec;
}
/* Compute the time remaining to wait.
tv_usec is certainly positive. */
result->tv_sec = x->tv_sec - y->tv_sec;
result->tv_usec = x->tv_usec - y->tv_usec;
/* Return 1 if result is negative. */
return x->tv_sec < y->tv_sec;
}
Los tiempos se toman en microsegundos (usec) y la velocidad lineal real de la rueda, que no tiene por qué ser la velocidad del viento cuando el invento esté montado, se calcula una vez por segundo y se hace a partir de los siguientes datos:
velocidad * 1000000 * 9 * 0.0174 * 0.9 * 3600 / 100000
Velocidad es la velocidad calculada tics por microsegundo. Se multiplica por 1000000 para tenerla en tics por segundo.
La rueda de mi ratón tiene exactamente 40 agujeros. Esto quiere decir que cada agujero representa aproximadamente 9 grados de circunferencia (360/40 = 9). Al multiplicar por 9 los tics por segundo, consigo la velocidad en grados por segundo. Como 1 grado = 0.0174 radianes (2*Pi/360), multiplico y obtengo la velocidad en radianes por segundo.
¿Para que necesito la velocidad en radianes / segundo?, porque esta es la velocidad angular y para averiguar la velocidad lineal de un punto del borde del disco dentado tengo la fórmula:
v = r * w (uve igual a erre por omega)
donde omega es la velocidad angular y r el radio de la circunferencia. Como el radio de la rueda de mi ratón mide 0.9 cm multiplico por esa cantidad y obtengo la velocidad en cm/s. Ahora solo queda multiplicar por 3600 segundos/hora y dividir por 100000 cm / Km y obtenemos la velocidad en Km/h.
Por supuesto esta expresión y otras partes del código se pueden simplificar, pero lo dejo así por motivos didácticos… vamos que si la simplifico no me entero ni yo de por qué he hecho lo que he hecho
Con este montaje y estos cálculos he logrado que la rueda alcance los 50Km/h. Supongo que si le meto 12V o quemo el motor, o consigo mas velocidad, pero no me preocupa demasiado ya que teniendo en cuenta que el anemómetro entero va a tener un radio de giro de 5 cm, para la misma velocidad angular, la velocidad del punto central de una cazoleta tendría que ser de ¡mas de 300 Km/h!
¡Esto no ha hecho mas que empezar! Os mantendré informados de los progresos.
junio 20th, 2007
En una partida de cartas, la tarea de calcular el valor de una mano para saber si gana a otra se llama evaluación de manos (hand evaluation). Para un ser humano que ha aprendido las reglas de un juego de cartas cualquiera, la evaluación de manos es una tarea trivial, nada mas ver las cartas sabe que un poker es mas que una pareja, o que dos reyes caballo ganan a dos reyes sota.
Pero para un ordenador la tarea no es tan sencilla si se quiere hacer de manera eficiente y la gente se estruja el cerebro para conseguir dar con algoritmos que realicen esta tarea rápidamente y sin errores.
Yo ya me vi una vez en esta tesitura cuando hice el juego de mus multijugador de Teknoland, el mus de Commm, y la verdad es que inventé un sistema bastante bueno que con las cartas ordenadas asignaba a cada una un valor que dependía de la fase que se jugaba y lo multiplicaba por una potencia de su posición en la mano. De este modo conseguía un número entero que me permitía comparar manos de distintos jugadores, la del entero mayor era la que ganaba (salvo en la chica, claro).
Ahora me veo en la misma tesitura pero para otro juego mucho mas popular que el Mus… el Poker.
Por ser tan popular existen variopintos algoritmos de cálculo de manos en internet, pero unos me han parecido demasiado complejos y otros demasiado simples y lentos, por eso he decidido poner las neuronas a funcionar y he dado con una formula, que puede que no sea tan rápida como la de Cactus Kev, pero que si es mucho mas elegante desde el punto de vista algorítmico y además permite solucionar el problema de cálculo de manos a partir de 7 cartas, que son las que se usan en la variante Texas Hold’em (después de la cantidad de spam que he borrado con estas dos palabras nunca pensé que llegaría a usarlas en un post
).
Voy a usar una máquina de estados (autómata finito determinista) para leer las cartas una tras otra, teniendo en cuenta el hecho de que la mano está ordenada de mayor a menor valor de carta, que estamos hablando de poker jugado con una sola baraja, sin comodines y sin quitarle las cartas bajas. Cuando acabe de leer las cartas, el valor de la mano me lo dará el estado en el que se encuentre la máquina. Es el mismo método que se usa en los reconocedores de patrones.
El diseño de este autómata de Moore contemplando todas las posibilidades se me ha antojado bastante complejo, por eso he decidido usar las reglas del poker para simplificar el problema teniendo en cuenta lo siguiente:
Si en las 7 cartas 5 son del mismo color, ya solo puedo conseguir “color” (Flush), “escalera de color” (Straight flush) o “escalera real” (Royal Flush).
Técnicamente también puedo conseguir un trio y una pareja si tengo color, pero color es siempre mejor que estas dos anteriores, por lo tanto las puedo ignorar.
Si no se cumple esta condición, entonces verifico si hay una “escalera simple”, y si tampoco, paso al autómata que me dirá si lo que hay en las cartas es una “pareja” (one pair), “doble pareja” (two pair), “trio” (Three of a kind), “ful” (full house) o “poker” (four of a kind).
Luego viene el autómata en si. Este autómata lee las cartas de una en una y las compara con la última que leyó. Tiene dos posibles entradas, que la última carta y la actual sean iguales, o que sean distintas. Dependiendo de estas entradas se va variando el estado de salida.
El diagrama de transiciones del autómata sería el siguiente.

En él se puede observar que de cada estado salen siempre 2 flechas, los dos posibles inputs. Los estados marcados como STOP hacen detenerse al autómata porque ya es imposible ningún otro estado.
La única excepción se da en el caso del “poker”, el estado 4, ya que después de haber leído 4 cartas iguales, es imposible que venga otra 5 igual (no hay 5 palos) por lo que el autómata irá a STOP irremediablemente en la siguiente lectura.
El resultado viene indicado por el estado en el que quede el autómata al terminar de leer todas las cartas o bien por el anterior al último en caso de que el último sea el STOP (normalmente antes de acabar de leer todas las cartas, con lo que nos ahorramos alguna iteración que otra).
En el diagrama se pueden observar unos estados marcados como “Fulín” y “Fulón”. Estas denominaciones las he tomado prestadas de las que mis amigos (Sireno, Cabezón, Tabique, Payaso, Gon, Joan…) daban en el juego del poker mentiroso con dados. Fulín significa que se trata de un full house en el que el trio lo forman las cartas de menor valor, mientras que el fulón es lo contrario, el trio lo forman las cartas de mayor valor. Un fulón no tiene sin embargo por qué ganar siempre a un fulín, por lo que en realidad ambos son tratados simplemente como “Full house” en el autómata (p.ej. 55533 es un fulón, y AAKKK un fulín… claramente el segundo gana). La distinción es simplemente semántica.
Para hacer mas eficiente el algoritmo de evaluación de manos, en la primera pasada solo calculo el tipo de jugada que hay en la mano, lo que denomino “major rank”. En la mayoría de los casos este dato es suficiente para determinar la mano ganadora y por tanto la resolución es muy rápida (p.ej. el major rank de AKJJ5 es “Pareja” y el de KQ7773 es “Trio”). En caso de que las manos a comparar tengan el mismo “major rank” (p.ej. dos manos con “Trio”) entonces pasaríamos a comprobar el “minor rank” (p.ej KQ7773 y QQQ52, el minor rank es 7 y Q respectivamente), para el que se necesitan mas cálculos. El minor rank depende del valor de las cartas que acompañan a aquellas que conforman el major rank.
Por último, en los casos que la mala suerte vestida de estadística nos proporcione dos manos con el mismo major rank y minor rank (p.ej. AAQQ5 y AAQQ6, el major es dobles parejas, el minor es ases y cues) tenemos que calcular un valor mas, el kicker, que servirá para deshacer el desempate. En el caso de que el kicker también sea igual, entonces las manos son iguales y hay un empate que obliga a repartir el bote a partes iguales.
Hay gente que calcula todo, el major rank, el minor y el kicker en una sola vez. Es una pérdida de tiempo ya que la mayoría de las veces no es necesario llegar tan lejos en las comparaciones para hacer una valoracion correcta de la mano ganadora.
diciembre 14th, 2006