Agregador de canales de noticias
Añadido el script deleteTables.sh
Añadido el fichero deleteTables.sh que elemina las tablas
actuales del sistema antes de la ejecución del software
nftables-gui
Commiter:
José María Caballero Alba
caballeroalba@gmail.com
Added:
deleteTables.sh
src/deleteTables.sh
Modified:
Deleted:
Commit:
Link
Onsite implementation and future development
Hey! The week from April 20th to 26th, DPMbox will be tested on site on CERN facilities in Geneva and presented to the IT-SDC-ID section, which is reponsible of DPM development.
I will update this entry with all the progress achieved and the feedbaack received there.
I’m excited, cheers!
Video Demo ARgos
El prototipo construido utiliza una cámara de bajo coste y un cañón de proyección portátil para mostrar información visual, directamente alineada sobre el documento del mundo físico.
Figura 1: Hardware de ARgosResponde a las peticiones que el usuario realiza sobre el espacio físico, ampliando información relacionada que sea relevante a la acción que quiera realizar. El documento se puede mover dentro de una región del escritorio y la amplificación queda perfectamente alineada en el espacio físico. Como soporte hardware, se ha utilizado un computador en placa Raspberry Pi con arquitectura ARM.
Las principales carácteristicas del sistema son:
Captura y preprocesado de imágenes. El sistema dispone de un módulo para obtener las imágenes y aplicarle el procesado previo necesario, como puede ser escalado, umbralización, detección de bordes o detección de características. Otra tarea que realiza, es calcular la distorsión debida a la proyección en perspectiva mediante los parámetros extrínsecos e intrínsecos de la cámara.
Sistema de identificación de documentos. ARgos cuenta con un sistema de identificación rápida empleando algoritmos de recuperación de imágenes y comparando el documento que está siendo analizado, con una base de datos de documentos conocidos por el sistema.
Implementación de técnicas de tracking y registro. Para el correcto alineado de la información mostrada, el módulo de tracking y registro cuenta con funciones de cálculo de pose (rotación y translación del objeto en el espacio 3D) en tiempo real y algoritmos para la estimación y descripción del movimiento como Optical Flow.
Utilización de paradigmas de interacción natural con el usuario (NUI). El usuario puede interactuar directamente en el espacio físico sin utilizar sistemas de mando o dispositivos de entrada tradicionales como un ratón, teclado, etc. siendo sustituidos por funciones más naturales como el uso de movimientos gestuales con las manos.
Facilita la gestión documental a personas con necesidades especiales. Cuenta con diferentes modos de amplificación de la información del mundo real. Por un lado, la información visual se amplifica empleando el cañón de proyección, que muestra información relevante al contexto directamente sobre el espacio del papel, así como la reproducción de audio, text-to-speech y alertas sonoras.
Se basa en componentes de bajo coste. Para facilitar la implantación real en el entorno de trabajo, el sistema funciona con componentes de bajo coste, incorporando mecanismos de corrección de distorsión y registro 3D totalmente software.
Dispositivo multiplataforma (hardware y software). El desarrollo de ARgos se ha realizado siguiendo estándares, tecnologías y bibliotecas libres multiplataforma, con el objetivo de que pueda ser utilizado en el mayor número de plataformas posibles tanto hardware (x86, x86-64 y ARM) como software (GNU/Linux, Windows o Mac).
Manual de Calibrado
El proceso de calibrado del sistema se ha creado como una utilidad independiente del sistema principal de ARgos. Una vez calibrado, la aplicación proporciona los ficheros YAML, con los parámetros intrínsecos y extrínsecos, que necesita ARgos para el calculo del registro.
El proceso está separado en una aplicación cliente (calibrationToolBox_client) que está alojada en la Raspberry Pi, y otra aplicación servidor (calibrationToolBox_server) que se podría ejecutar en cualquier otro equipo.
En un principio se diseñó como un único programa que ejecutaba en la Raspberry Pi, pero si se tomaban muchas capturas para conseguir una calibración más precisa, el sistema se ralentizaba, y el tiempo de calibrado crecía excesivamente.
Se ha empleado esencialmente el enfoque de Zhang [1] para calibrado de cámaras. Se utiliza un patrón tipo tablero de ajedrez, en la que se alternan cuadrados blancos y negros, de dimensiones conocidas. El patrón se imprime y se pega sobre una superficie plana rígida.
Patrón tipo tablero de ajedrez
Se debe dejar una zona despejada a continuación del tablero de ajedrez, ya que en esta zona se proyectará el patrón que utiliza el proyector para su calibrado. Se debe prestar atención en que orientación es pegado, ya que si se colocase al revés, la proyección dinámica se realizaría fuera del panel.
ConfiguraciónAntes de iniciar el proceso de calibrado, debemos definir los parámetros de configuración. Tomamos la medida del lado de un cuadrado para proporcionarla al programa de calibrado, de esta forma las unidades de medida del sistema de referencia se corresponden a medidas reales.
Además del tamaño del lado debemos indicar el número de esquinas en vertical y horizontal que tiene el patrón que estamos utilizando. Gracias a esto, no estamos atados a realizar el calibrado con un patrón particular, que tenga unas medidas concretas. Basta indicar las características del patrón que vamos a utilizar para realizar un calibrado correcto.
Los otros dos parámetros de la configuración, corresponden al desplazamiento (en los ejes X e Y) de la proyección del patrón de círculos asimétrico. El objetivo es ajustar la visualización de la proyección para que el patrón proyectado aparezca junto al patrón impreso.
Los últimos parámetros son las dimensiones de las imágenes, tanto de la cámara como del proyector. Se pueden utilizar resoluciones distintas, pero en ARgos, se he optado por utilizar la misma en ambos dispositivos.
Calibrado de la cámaraA continuación, colocamos la superficie bajo la cámara, en distintas orientaciones y distancias, para obtener una serie de imágenes en los que se encuentre visible el patrón.
Cuando el proceso disponga de al menos 20 imágenes válidas, realizará los cálculos para obtener los parámetros intrínsecos de cámara y los grabará en el fichero calibrationCamera.yml
Se considera una captura válida aquella que al aplicar los cálculos de calibrado, devuelve un error de reproyección menor de 0.25.
Calibrado del proyectorEl siguiente paso consiste en calibrar el proyector. Al comienzo de este estado, se proyecta un patrón de círculos asimétrico, en una posición fija.
Patrón de círculos asimétricosColocar la superficie, de tal forma, que el patrón proyectado quede junto al del tablero de ajedrez. Volver a mover el patrón el espacio de la proyección hasta que el sistema adquiera 5 imágenes más. Para la aceptación de estas 5 imágenes, el error de reproyección cometido no debe ser mayor de 0.35.
Calibrado estereo (camara-proyector)En ese momento, la calibración pasa al modo dinámico, y los puntos proyectados se generan en función de la posición que se encuentre el tablero de ajedrez.
Tras capturar 15 imágenes con los puntos dinámicos, se refinan los cálculos correspondientes a los parámetros intrínsecos del proyector, y finalmente, se calculan los parámetros extrínsecos (matrices de rotación y traslación) entre la cámara y el proyector.
Los parámetros de calibrado se almacenan en los ficheros calibrationProjector.yml y cameraProjectorExtrinsics.yml.
Test de verificación del calibradoUna vez realizada la calibración se iniciará un test para comprobar que se ha hecho correctamente. El test consiste en proyectar un círculo sobre las cuatro esquinas exteriores del patrón de tablero de ajedrez. Al mover el patrón los puntos proyectados deben siempre permanecer alineados con las esquinas.
ConclusionesTanto el número de imágenes que se deben detectar antes de pasar a la siguiente fase, como los errores de reproyección máximos permitidos por la cámara y el proyector, son también configurables. Tras realizar numerosas pruebas variando estos parámetros, los mejores resultados manteniendo el compromiso precisión-tiempo-consumo, se llega a la conclusión que los valores antes descritos son los que mejor se ajustan.
Tal y como se describe, el proceso completo de calibrado se puede realizar en varios minutos. Asimismo, mientras que la cámara y el proyector mantengan su posición y rotación entre ellos, no es necesario realizar una nueva calibración y es posible desplazar todo el sistema.
[1] Zhang, Zhengyou. Flexible camera calibration by viewing a plane from unknown orientations. Proceedings of the Seventh IEEE International Conference on Pattern Analysis and Machine Intelligence, 1999. Páginas 666-673
Prototipo virtual de ARgos
En una de las primeras etapas del proyecto y para probar la arquitectura de red, se decidió realizar un modelo virtual de todo el sistema ARgos, que únicamente mostrara las matrices de transformación calculadas por el sistema.
Este modelo del sistema cumplía con las siguientes características:
- Visualización directa del entorno del sistema.
- Envío de fotogramas a través de red mediante sockets.
- Envío de matrices de modelo, vista y proyección del documento a través de la red.
- Visualización en tiempo real de los fotogramas y matrices recibidas en el servidor.
- Interacción del usuario con diversos elementos del entorno mediante teclado y ratón.
En este post únicamente se comentarán las partes relevantes del prototipo que tengan que ver con la retransmisión de las imágenes, entre otras cosas.
El sistema se ayuda de una primitiva versión cliente de la clase TaskDelegation de BelfegAR, la cual inicia un bucle de envío de información constante al servidor. La información enviada se compone de las matrices de modelo, vista y proyección, y del fotograma capturado por la cámara en ese momento. La información es copiada en un buffer como una secuencia de bytes y transmitida al servidor para su procesado. Cabe destacar, que los sockets UDP por estándar no permiten el envío de paquetes que ocupen más de 65536 bytes, por lo que la imagen se comprimía en JPEG manteniendo un 80% de la calidad original. A continuación se muestran los métodos empleados para construir el buffer de datos que se enviarán al servidor.
void TaskDelegation::addMatrix(const float* matrix) { int size = 16 * sizeof(float); unsigned char sMatrix[size]; memcpy(sMatrix, matrix, size); _buff.insert(_buff.end(), &sMatrix[0], &sMatrix[size]); } void TaskDelegation::addCvMat(const cv::Mat& mat) { std::vector<unsigned char> mat_buff; std::vector<int> params; // Compress the image, since UDP packet <= 65536 bytes params.push_back(CV_IMWRITE_JPEG_QUALITY); params.push_back(80); cv::imencode(".jpg", mat, mat_buff, params); int length = mat_buff.size(); unsigned char packet_size[sizeof(int)]; memcpy(packet_size, &length, sizeof(int)); _buff.insert(_buff.end(), &packet_size[0], &packet_size[sizeof(int)]); _buff.insert(_buff.end(), mat_buff.begin(), mat_buff.end()); }Se muestra también a continuación el bucle de envió de datos que ocupa a la aplicación:
... // Initializing stuff cv::Mat currentFrame; TaskDelegation* td = NULL; if(argc > 1) { td = new TaskDelegation(); td->setEndpoint(argv[1], argv[2]); // [1] -> ip | [2] -> port } while(1) { ... // Gets camera frame and store it in the currentFrame object if(td) { td->addMatrix(projection_matrix); // Adds a matrix (float[16]) td->addMatrix(modelview_matrix); // Adds another matrix td->addCvMat(currentFrame); // Adds a cv::Mat td->send(); // Sends the built buffer through the socket } ... } ...Una vez enviada la información, se procede a su procesado en el servidor, mediante un script Python ejecutado por la aplicación construida en Blender.
A continuación se muestra el código del servidor que permanece a la espera de recibir la información del cliente y el código de las funciones que procesan las matrices y fotogramas recibidos.
def listen(cont): global sock obj = cont.owner while 1: data, addr = sock.recvfrom(32768) ... raw_matrix = data[0:64] buff.append("\n> Projection Matrix:\n") buff.append(getPrintableMatrix(parseMatrix(raw_matrix))) raw_matrix = data[64:128] buff.append("\n> ModelView Matrix:\n") buff.append(getPrintableMatrix(parseMatrix(raw_matrix))) cv_mat_length = data[128:132] mat_length, = struct.unpack("<i", cv_mat_length) raw_cv_mat = data[132:len(data)] parseCvMat(raw_cv_mat) ... def parseMatrix(raw_matrix): m = struct.unpack("<16f", raw_matrix) # Unpack matrix from C memcpy m = ["{:.2f}".format(i) for i in m] # 2 decimals per element m = [[m[0], m[4], m[8], m[12]], # Set to row-major order [m[1], m[5], m[9], m[13]], [m[2], m[6], m[10], m[14]], [m[3], m[7], m[11], m[15]]] return m def parseCvMat(raw_cv_mat): f = open("frame.jpg",'wb') f.write(raw_cv_mat) # Writes the received image to disk f.close() # in order to display it afterUna vez recibida y procesada la información, solo queda mostrarla mediante Blender y permitir la interacción del usuario, la cual se realiza mediante las teclas de movimiento WASD y el botón izquierdo del ratón.
A continuación se muestran algunas capturas de la aplicación desarrollada.
Aquí podemos ver una vista general del prototipo. Existen varios elementos interaccionables en la escena, como el portátil, el cual es el elemento principal del prototipo y sobre el cual se encuentra integrada toda la lógica.
Cuando interactuamos con el portátil se arranca un servidor que permanece a la escucha después de iniciar un socket UDP.
Cuando ARgos envía información al prototipo, el portátil empieza a mostrar información sobre las matrices de transformación de los documentos detectados.
Aquí podemos ver el fotograma recibido en tiempo real capturado por ARgos.
Iteraciones (ARgos Client)
Explicadas las iteraciones que se llevaron a cabo para el desarrollo del servidor, se presentan a continuación las iteraciones de cliente.
Iteración 1En esta primera iteración, se empezó implementando el sistema de superficies aceleradas por hardware mediante EGL para conseguir un contexto de OpenGL ES funcional y estable. Se implementó además la carga, compilación, enlazado y activación de programas OpenGL basados en shaders.
Se creó también el primer componente gráfico; RectangleComponent. Éste solo se dibujaba de forma fija en el escenario, y la posición llegó a controlarse modificando directamente los vértices de la figura en lugar de aplicar matrices de transformación.
Pese a que todo acabó funcionando correctamente, surgieron varios problemas al emplear la versión empotrada de OpenGL, ya que al emplear un cauce programable, la dificultad aumentaba al eliminar el uso de las matrices MODELVIEW y PROJECTION, y las correspondientes operaciones con los métodos glPushMatrix y glPopMatrix para operar sobre ellas. También se eliminó de esta versión los métodos de construcción de objetos 3D, como glBegin, glVertex y glEnd, pasándose a utilizar listas de vértices con el shader correspondiente para su renderizado. El nuevo modo de funcionamiento supuso a OpenGL el soporte de paralelismo en su cauce de renderizado, además de aumentar el rendimiento general de las operaciones, al no dejar toda la carga al procesador, en el que se requería al menos la invocación de una función por vértice.
La meta que se propuso para esta primera iteración fue conseguir un contexto de OpenGL ES sobre el que poder trabajar, la instalación de dependencias del proyecto y la generación de los Makefiles necesarios para su construcción.
Iteración 2Una vez obtenido un entorno de despliegue gráfico funcional con un primer componente gráfico, se procedió a mejorar dicho componente para que se le pudieran aplicar varias transformaciones 3D. La primera transformación que se probó fue la de translación, para comprobar si funcionaba correctamente. Una vez implementada, se implementaron operaciones para escalar y rotar la figura.
Se creó además un nuevo componente gráfico; LineComponent. A partir de este, se comprendió mejor el uso de las listas de vértices. Manipulando los colores de las líneas e instanciando tres de ellas, se consiguió crear un eje de coordenadas.
También se investigó el tema de la compilación cruzada, ya que la construcción del sistema usando directamente la Raspberry Pi podía durar varios minutos.
En esta iteración, se afianzaron los conocimientos sobre OpenGL ES 2.0 y se ideó un nuevo componente gráfico. También se aplicaron las primeras transformaciones que permitían mover, escalar y rotar un objeto. Por último se empezó a hacer uso de un entorno de compilación cruzada para construir el sistema.
Iteración 3En esta iteración GrayAR ya podía detectar documentos y proporcionar sus matrices de modelo y vista, además de la matriz de proyección del entorno. Gracias a esto, se pudieron aplicar dichas matrices a los componentes gráficos para posicionarlos sobre los documentos.
Surgieron ciertas confusiones al principio relacionadas con las unidades del mundo de OpenGL y las definidas como centímetros en la realidad.
Se realizó un refactorizado completo a los dos componentes gráficos existentes, extrayendo comportamiento y atributos comunes y se creó la clase abstracta GraphicComponent, de la cual heredarían el resto de componentes gráficos en el futuro.
Se creó además el componente gráfico ImageComponent, el cual suponía el reto de cargar imágenes desde disco. Se estudiaron por tanto algunas bibliotecas que aportaran dicha funcionalidad, deduciendo que era la mejor opción, por ser una biblioteca pequeña y que solo realiza la función que queríamos: cargar imágenes.
También se creó en esta iteración el componente de texto o TextComponent, necesario para renderizar texto, usado en primera instancia para mostrar el número de fotogramas por segundo que alcanzaba el sistema.
Esta iteración concluyó de esta forma con un sistema de componentes gráficos ya afianzado, y fácilmente escalable y mantenible, que se adaptaban correctamente al documento.
Iteración 4GrayAR requería una forma de mostrar un patrón de círculos configurable para su herramienta de calibración. Por ello, se ideó un nuevo componente gráfico que permitiera dibujar círculos de forma sencilla; CircleComponent. La lógica de creación del círculo fue realizada en el propio shader para aliviar la carga de la unidad. Esto supuso el estudio más en profundidad del lenguaje .
También se creó un componente gráfico que permitiera cargar vídeos desde el disco; VideoComponent. Debido a limitaciones de tiempo, se decidió realizar la decodificación del vídeo por software mediante OpenCV.
Debido al bajo rendimiento que ofrecía la plataforma, se ideó una arquitectura de red que permitiera ejecutar las tareas de visión por computador en una máquina de mayor potencia. Se esbozó pues una primera versión del subsistema de delegación de tareas, que permitía el envío de matrices serializadas por red, mediante sockets .
Los resultados de esta iteración pues, fueron el desarrollo de dos nuevos componentes gráficos y un primer esbozo del subsistema de delegación de tareas.
Iteración 5En esta iteración, se consolidó el subsistema de delegación de tareas, permitiendo enviar más tipos de datos por red y estructurando el sistema de tal forma que hiciera un uso obligatorio de la delegación de tareas.
Se implementó también la arquitectura del subsistema de comunicaciones para poder migrar GrayAR al servidor. Con la arquitectura de red montada, se estableció el contrato de comunicación que debían seguir tanto el cliente como el servidor para la transmisión de la información.
A estas alturas del desarrollo, el sistema ya contaba con la arquitectura necesaria y escalable para añadir nuevos componentes gráficos y tipos de datos en la comunicación cliente-servidor.
Iteración 6Una vez establecida una arquitectura cliente-servidor funcional, se pretendió cubrir en esta iteración el sistema de soporte al usuario mediante videollamadas con la creación del VideoStreamComponent. Para ello, se tuvo que cambiar la arquitectura del servidor para soportar una nueva comunicación a través de otro puerto. Se implementó una comunicación mediante sockets paralela a la comunicación principal de los subsistemas de delegación de tareas y comunicación para el envío de vídeo desde el servidor.
También se implementó cierta interacción primitiva con el usuario, de tal forma que el cliente decidía que componentes gráficos mostrar en función del documento analizado. Esta primera aproximación permitía darle la vuelta al documento para iniciar una videollamada, de tal forma que el documento por detrás conformaba otro identificador distinto a la otra cara, y cancelarla al volver a darle la vuelta.
Esta iteración concluyó con la implementación funcional del componente de videollamadas y una primera aproximación a lo que sería la interacción del usuario con el sistema.
Iteración 7En vistas a crear componentes gráficos más complejos a partir de otros ya existentes, y como si de un programa de dibujado se tratará, se creó el RenderToTextureComponent. Se ideó en primera instancia para crear mensajes de ayuda que indicaran al usuario las posibles acciones a realizar con el documento.
El estudio del uso de la técnica de «render a textura», requirió cierto tiempo por introducir una gran variedad de nuevos conceptos como framebuffers compuestos de renderbuffers y texturas, además del uso de una matriz de proyección ortogonal única para este componente.
Finalmente, se creó un método ayudante para construir dichas ayudas al documento mediante parámetros como el tamaño de la imagen de ayuda, su color y los mensajes que contendría.
Esta iteración concluyó con la creación de un componente gráfico que permitía formar nuevos componentes más complejos, y un método para crear uno de esos componentes específicos.
Iteración 8Debido a la cantidad de componentes gráficos existentes a estas alturas del proyecto, se creo un gestor que se ocupara de administrar su creación, actualización, dibujado y destrucción, es decir, su ciclo de vida completo. Estamos hablando de la clase GraphicComponentsManager.
También se creó un contenedor de componentes gráficos o GCCollection que permitiera la gestión conjunta de componentes que compartieran cierto propósito. Desde este momento, el gestor de componentes gráficos se encargaba de administrar estos contenedores.
El gestor también proporcionaba métodos creacionales de componentes gráficos complejos como botones y paneles de texto empleando componentes de «render a textura», y videollamadas sobre superficies de imagen mediante colecciones de componentes individuales.
El objetivo de esta iteración se vio reflejado en el afianzamiento del subsistema de representación gráfica.
Iteración 9Con el subsistema de representación gráfica finalizado, se inició y completó el desarrollo del subsistema de audio en esta iteración.
Se adquirió una placa con altavoz integrado que se conectó a la Raspberry Pi para proporcionarle posibilidades de audio, ya que por defecto ésta no incluye características de sonido.
Se empleó una frecuencia de 16.000 Hz para la reproducción de sonidos, la cual proporcionaba una calidad adecuada al altavoz utilizado.
También se realizaron algunas mejoras en el código fuente, y se corrigieron algunos bugs. Después se realizó un refactorizado global para eliminar funciones y partes de código obsoletas.
Esta iteración supuso el funcionamiento de la mayor parte del sistema. Solo quedaba especificar las acciones a realizar por cada documento analizado.
Iteración 10En la iteración final, se estudió una manera de facilitar al usuario la especificación de diferentes acciones a realizar para ciertos documentos. Se ideó pues el subsistema de scripts, que permitía definir archivos interpretables por el servidor para su procesado y posterior envío de resultados al cliente.
El desarrollo del subsistema de scripts se basó en una implementación ya realizada para el del «Curso de Experto en Desarrollo de Videojuegos (3ra. edición 2013/2014)», The Secret of Liches [1]. La nueva implementación supuso una mejor estructura del código y un mayor uso del polimorfismo para la invocación de funciones scripteables desde C++.
Durante esta iteración, también se escribió parte de la documentación del proyecto y el manual de usuario del sistema, entre otros documentos como el manual de compilación cruzada, que en un principio se encontraba externo a este documento.
[1]: Vídeo del videojuego disponible en https://www.youtube.com/watch?v=J5ap3Gi4Dq8
Servidor web en marcha
He creado este sitio web con el programa, de modo que cualquier persona pueda ya visitarlo y empezar a usarlo.
Todavía me quedan más actividades por añadir (y añadir el resto de las consonantes a las que ya hay), pero creo que ya se puede apreciar su utilidad.
Ahora le pasaré el enlace a algunas maestras, para que lo valoren y me digan su opinión, sugerencias, críticas... Y a la vuelta de vacaciones, ¡a seguir programando!
Adaptación para dispositivos móviles
Además, ahora el lienzo se adapta al tamaño de la pantalla (al menos en Chromium, parece que cada navegador utiliza su propia versión de las etiqueta transform de CSS3, por lo que tendré que añadir las de los más populares).
Lanzamiento de la versión 1.1
Hace dos semanas añadimos la librería C10N para hacer la localización de una forma más sencilla dentro del código sin tener que trabajar directamente con los resource bundles nativos de java.
Despues de esto, os pedimos ayuda para añadir soporte a otros idiomas. Lo compartimos en las redes sociales, lo re-compartieron y ¿cuál fue nuestra sorpresa? Nada más y nada menos que TRES pull request para acabar añadiendo la tradución a alemán, ruso y francés. Ha sido increíble ver cómo la comunidad arrima el hombro y ayuda en el desarrollo de MazeSolver aumentando su alcance gracias a las traducciones. Damos las gracias a Getshi, rodionmoiseev y AL3XEY por su colaboración.
Debido al impacto que tuvieron las traducciones hemos decidido ponernos manos a la obra, refactorizar lo que hicimos y facilitaros el trabajo, porque ¡sois increíbles y os lo merecéis! Hemos sacado las traducciones del código y las hemos puesto en ficheros separados. ¿En qué ayuda esto? Ahora añadir otro idioma es tan fácil como copiar el fichero resources/translations/Translations.properties, ponerle el mismo nombre pero acabado en _location (mira aquí para consultar el sufijo que hay que añadir para un idioma específico), traducirlo y abrir un pull request. Pero ya sabes, si tienes alguna duda estamos a tiro de issue :wink:.
Y aquí estamos, presentándoos la nueva versión 1.1 de MazeSolver, que incluye todo lo que tenía previamente y soporte multilenguaje con 5 idiomas incluidos (español, inglés, francés, alemán y ruso): DESCARGA.
Saludos
El equipo de MazeSolver
Issue 127: It's alive!
Estimado Evaluador
Estimado evaluador:
Vistas las fechas, suponemos que tarde o temprano pasarás por aquí, y puesto que somos conscientes de que el nuestro no es un “proyecto convencional” de software o hardware libre, te dedicamos este post para que puedas evaluarlo en su totalidad, sin perderte nada.
¿En qué consiste el proyecto Open Tiny Crazy World?
Se trata de una plataforma educativa Open source que presenta el aprendizaje desde el juego y la motivación, desarrollándolo en el tiempo libre.
¿Qué incluye la plataforma?
Incluye todo nuestro material educativo, que podemos separar en tres grandes bloques:
- Tiny World: “El mundo a pequeña escala”. Es el grueso de nuestro desarrollo, alrededor del cual orbita toda la plataforma: Se trata de un juego de construcciones masivo Open Source. Con “masivo” queremos decir que está preparado para incluir conducción eléctrica y elementos electrónicos de potencia estándar. Comenzamos con LED’s y motores, pero es nuestra intención implementar en un futuro conceptos a priori tan complejos como señal, servos, bobinas, condensadores, sensores y control con un sistema de programación gráfica sencilla (Algo tipo scratch) dentro del sistema. Lo necesario para dar forma de un modo simple y seguro a prácticamente cualquier construcción móvil, funcional, e incluso robótica que se nos ocurra. Dicho rápidamente, hablamos de un sistema abierto de chasis universal en forma de juguete de construcciones.
Todo esto, sin embargo, lleva un largo proceso de desarrollo, que empieza por crear un sistema mecánico de piezas que sea funcional y permita estructuras resistentes, de modo que avanzamos poco a poco para no tropezar con las prisas. Las partes que hemos podido desarrollar para presentar a concurso son:
Piezas Arista electrónica: e50 y e100.
Pieza Arista mecánica: a50 y a100.
Piezas Nexo electrónico: e2s, e4s y e6s.
Pieza soporte para pilas.
Pieza Led.Para seguir nuestro desarrollo por versiones y ver la evolución de nuestro sistema, podéis visitar nuestro banco público de trabajo, disponible en Grabcad (Donde sólo se puede ver, no descargar). Para descargar las versiones finales de las piezas, utilizamos nuestro perfil de Thingiverse. También tenemos publicada la cronología del desarrollo del nexo básico en los siguientes posts:
En enganche básico (I) (II) y (III) - Crazy World. Haciendo estudio de mercado, hemos observado juguetes de construcciones que se hicieron con el sector (Como Lego), otros conocidos pero no tan mediáticos (K’nex) y otros, como Construx, que fueron desbancadas por la competencia. ¿El motivo? Una de las grandes diferencias que vemos es la ambientación: Saber presentar el juguete de una forma atractiva para l@s niñ@s, tal que les invite a jugar, avivando sus ganas de utilizar la imaginación. Así pues, en Crazy World, nuestro sistema de ambientación, presentamos a los Minus, nuestras simpáticas mascotas, que son el equivalente didáctico a los electrones. Los Minus viven felices sus vidas, haciendo cosas y pasándolo en grande… ¡hasta que el fenómeno conocido como potencial positivo aparece en su entorno y su naturaleza les obliga a correr hacia él sin poder evitarlo! Se trata de una iniciación básica y divertida al principio de la conducción eléctrica, que empieza por un Minus y termina… creciendo en todas las direcciones posibles.
Hay mucho planeado: Juegos, aplicaciones, historias dentro de historias y un hilo argumental definido, que explicarán poco a poco diferentes conceptos electrónicos que más tarde se aplicarán en el juego físico, pero no es tanto lo que podemos presentar por el momento (Todos nuestros materiales deben crecer uniformemente a la misma velocidad para que la plataforma sea estable) Por el momento, presentamos el desarrollo artístico de los Minus y alguna tira cómica que explica su naturaleza. Sin pausas pero sin prisas.
Material artístico: Los Minus. - El servicio. El gran debate alrededor del software libre tiene como origen el modelo de rentabilidad, que muchas veces se difumina en la idealidad. ¿Cómo hacemos a la sociedad más afín al software libre? Desde Open Tiny Crazy World nos gustaría desarrollar este aspecto y sumarnos a ese conjunto de referentes que encontramos en la sociedad que ha conseguido rentabilidad a partir de la filosofía OpenSource (Arduino, Raspberry Pi y otros distribuidores y empresas con la cultura Maker como base). En nuestro caso, comenzamos por crear un servicio alrededor de nuestro producto tal que merezca la pena pagar por él. Como en los casos anteriores, ideas hay muchas, pero no queremos perdernos en lo que “podría llegar a ser”, sino en lo que actualmente es. Algunas de nuestras recetas incluyen la venta activa por medio de actividades para niñ@s en distintas ciudades donde se muestre el sistema de construcción y juego “Tiny World”, apropiadamente introducido con nuestra ambientación “Crazy World”, complementando las jornadas con distintas actividades de educación en nuevas tecnologías, la cual consideramos imprescindible en la sociedad. Estas actividades también forman parte del material libre de la plataforma Open Tiny Crazy World, y están a la disposición de una comunidad de desarrolladores que las complemente, mejore y de un buen uso. Nuestro primer ejemplo de actividad-tipo se puede encontrar en nuestra pestaña de actividades. También es posible ver la memoria de la puesta en práctica de la misma que tuvo lugar el 21/3/15 en la Universidad Miguel Hernández con niñ@s del Grupo Scout San Rafel de Elche con muy buenos resultados.Open Tiny Crazy World es un proyecto nacido de las ganas de crear, la ilusión por dar y recibir y la necesidad de se comprenda la educación como una motivación más que como un proceso arduo y complejo. Cada pequeño detalle ha sido hecho pensando en seguir adelante con ello y convertir el proyecto en una realidad en la que cualquiera pueda disfrutar de nuestro trabajo. Queremos hacerlo grande y realmente tenemos la motivación para ello.Muchas gracias por leernos hasta el… “no final”.
Atentamente;
El equipo de Open Tiny Crazy World.
Más actividades con sílabas
En ésta, el niño tiene que comparar la palabra indicada con la de los dibujos, y arrastrarla hasta el dibujo que coincide:
En esta actividad, el niño tiene que identificar la sílaba que falta:
Y en ésta tiene que reconocer la palabra del dibujo (basta con reconocer la sílaba inicial), y arrastrarla al dibujo:
Cambiados todos los nombres de los metodos
.
Se ha cambiando todos los nombres de los metodos y variables
para una mejor lectura del código, por ej:
Se ha cambiado NFTABLES_GUI_ATTR_TABLE_NAME POR NFTGUI_TABLE_NAME
De esta manera se puede leer mucho mejor el código
Commiter:
José María Caballero Alba
caballeroalba@gmail.com
Added:
Modified:
src/chain.c
src/chain.h
src/main.c
src/prototypes.c
src/rule.c
src/rule.h
src/table.c
src/table.h
Deleted:
Commit:
Link
¡Testíng!
Como comentábamos en una entrada anterior, se ha utilizado la placa de desarrollo STM32F4-Discovery provisionalmente para facilitar el desarrollo del firmware, debido a que ésta dispone de depurador.
Se ha desarrollado una pequeña aplicación de test que utiliza las dos bibliotecas que se han creado (para el LCD y para la IMU). En este test leemos los datos de la IMU y los mostramos en la pantalla de dos formas distintas: mediante una gráfica temporal y con texto. También se ha dibujado una especie de reloj con el fin de depurar el comportamiento del algoritmo de trazado de lineas.
Debido a que las librerías utilizadas para la gestión de los periféricos y la configuración del micro no son libres, no voy a subir este código al repositorio. Dejo un enlace aquí por si a alguien le es de ayuda: https://drive.google.com/file/d/0B2X0VWywUQgtZjRYQmN3QzFySFU/view?usp=sharing
A continuación se muestra un pequeño video del montaje en funcionamiento.
Biblioteca IMU
El sistema utilizará una IMU (MPU6050 de InvenSense) para obtener información sobre su verticalidad. Este dispositivo, que se comunica mediante I²C, tiene una configuración algo compleja. Para utilizarlo se ha buscado una biblioteca de software libre que facilitara el trabajo.
La biblioteca elegida está bastante completa y bien documentada, pero es específica para los micros de la familia STM32f103xx. Por esto se ha optado por crear un fork donde se ha trabajado en eliminar las dependencias de hardware de la biblioteca y crear una capa BSP.
La dependencia de la biblioteca respecto al periférico I²C aún puede gestionarse algo mejor, añadiendo parte del protocolo de comunicación a la biblioteca y delegando en el usuario la implementación de un BSP mínimo.
Enlace al repositorio: https://github.com/FarK/MPU6050-Generic-RTOS
Versión alfa para la evaluación del concurso software libre.
Buenos días, de nuevo vuelvo a publicar los resultados diarios del desarrollo, hasta ahora, por falta de tiempo debido a la carrera y unas prácticas las cuales me hicieron perder un mes, pero bueno, la mayor dificultad ha sido no tener ninguna idea sobre C.
Gracias a un curso que estoy dando en centro de formación continua de la universidad de Sevilla, he mejorado mucho mi nivel de c.
Aunque es muy bajo todavía y esto se nota en el código la falta de experiencia en este lenguaje, pero gracias a mi profesor de la universidad Pablo Neira y a mi profesor del curso de c Alvaro Neira, he avanzado a pasos agigantados para este proyecto, que también forma parte de mi proyecto de fin de carrera, por lo cual, después del concurso seguirá desarrollándose hasta llevarlo a una versión estable sin fallos.
Pero vamos al tema:
Para paliar la temprana edad de este software por el poco tiempo de desarrollo, he decidido recortar un par de funcionalidades de cara al concurso, para evitar que pudiera fallar por cualquier fallo relacionado con la experiencia (segmentaciones de memoria, fugas, punteros inválidos, etc y sobretodo ncurses) . Básicamente, nftables-gui puede hacer ahora mismo de manera correcta lo siguiente:
Crear tablas de tipo ip, ip6, arp y brigde
Crear cadenas de tipo base (las de tipo no base se desarrollará en el futuro próximo)
Crear reglas pudiendo elegir protocolo tcp o udp, puertos destino y origen y las acciones sobre los paquetes drop, reject, accept.
Todo esto esta controlado de la forma que la aplicación no deja seguir adelante si los datos se introducen de manera inadecuada (tablas/cadenas/reglas vacías, cadenas no base, acciones no starndard etc).
Igualmente, este desarrollo seguirá en adelante para cumplir los siguientes requisitos de cara a junio:
Crear tablas de tipo ip, ip6, arp y brigde
Crear cadenas de tipo basey no base
Crear reglas pudiendo elegir protocolo tcp o udp, puertos destino y origen , las acciones sobre los paquetes drop, reject, accept, jump, interfaz, ip origen y destino, red origen y destino.
Exportar y importar reglas en el formato de nftables.
Leer tablas actuales del sistema y usarlas para editarlas desde nftables-gui, etc.
También se ha llevado a cabo el uso de buenas pracitcas como:
hacer uso del kernel style.
Apis para el correcto uso de memoria de las estructuras.
Api genérica la la creación de las interfaces de ncurses.
En definitiva, para el tiempo de desarrollo (apenas un poco mas de un mes) estoy bastante contento con el desarrollo ya que hay mas asignaturas, proyectos, etc.
Muchísima suerte a todos los participantes!
Primera actividad con sílabas
En la primera parte, hay que seleccionar el dibujo que empieza igual que el indicado.
En la segunda, hay que seleccionar la sílaba por la que empiezan ambos dibujos.
Una cuestión que me está llevando mucho tiempo es encontrar dibujos libres que representen claramente la palabra en cuestión. Muchas veces tengo que desistir de usar una determinada palabra.
Tutoriales, manuales, información a tutiplén
Buenas tardes queridos lectores.
Se acerca el día de la verdad; el día en el que algunos señores o señoras oscuros van a indagar en nuestro trabajo y decidir: “Fame or Shame”. Pero estamos tranquilos porque hemos hecho las cosas bien, ¿verdad que sí señor/a oscuro/a?
Pero no venimos a hablarles de eso. Queremos avisar de que estos últimos días hemos estado preparando documentación para todos los distintos perfiles a los que MazeSolver va dirigido: Desarrolladores, investigadores de estrategias de búsqueda en IA y todo aquel friki al que le molen los laberintos.
- Para los desarrolladores: Tenemos para ustedes un tutorial de creación de agentes en MazeSolver. ¿Tienes algún mínimo conocimiento de Java o Programación Orientada a Objetos? Si la respuesta es que sí o que no, entonces este tutorial es para tí. Se ha hecho pensando en todos los detalles, por lo que esperamos que prácticamente cualquier idea se pueda realizar utilizando los conceptos básicos presentados.
- Para los investigadores de estrategias de búsqueda en IA: El tutorial de creación de agentes será algo que tal vez sería conveniente que echaran un vistazo, aunque probablemente tienen ya a algún becario que les escriba el código :lol:. En cualquier caso enlazamos un informe de la aplicación que se centra más en los aspectos de IA de la aplicación, por si esto les produce algún tipo de inspiración. Enlace.
- Para los anteriormente nombrados y la gente en general: Para aquellos que miraron la aplicación por un momento y no supieron qué hacer hemos redactado la guía de usuario de MazeSolver 1.0, porque somos así de buenos.
Y además de todo esto tenemos más noticias en camino, pero no será hoy cuando las revelemos. Manténganse atentos porque aún no hemos acabado.
Pásatelo pipa,
El equipo de MazeSolver
El enganche básico: La arista e50 y el nexo e4s (III)
Teníamos un nexo incompleto (A falta de una tapa superior) y una arista que no nos convencía, no siendo tan apta para la impresión 3D como nos habría gustado (Hacía necesario imprimir con puentes, lo cual no siempre daba buenos resultados). Por suerte, tan pronto pudimos experimentar con el encaje básico se nos ocurrió un encaje alternativo, que nos quitaba la necesidad de trabajar con puentes y hacía la unión mucho más estable.
Nuestra solución fue quitar la pestaña y poner unas ondulaciones en los extremos de la piesta arista, de forma que el nexo tuviera la misma curva de entrada para que entrara como entrara la pieza, tuviera sujección. El resultado fue de lo más satisfactorio.
Además, para facilitar la inserción de los muelles en la pieza nexo e4s, decidimos finalmente dividirla en dos partes (Lo cual a la larga facilitaría el trabajo a pesar de tener que pegarlas). En este modelo conservamos la cavidad para encajar los clavos que se sueldan a los extremos de la pieza e50, con espacios habilitados para situar esas soldaduras y siendo necesario un solo nervio en el punto medio de la pieza arista para asegurar una buena resistencia mecánica.
En la figura podemos ver también dos pequeños orificios en los lados a lo largo de la pieza. En una mitad A, tendremos un saliente que será entrante en la mitad B, facilitando el ensamblaje de ambas partes.
En la planta de la pieza nexo e4s, vemos las ondulaciones que facilitan el encaje con la arista colocada en cualquier posición.
En este caso, las mitades A y B de la pieza encajan fácilmente a través de las cuatro esquinas del cuadrado central, que en una parte son salientes y en otra entrantes. Ambas piezas están adaptadas para ser impresas en 3D sin dificultades; también están pensadas para que en un futuro se puedan mecanizar en un sistema de inyección de plásticos por medio de un molde.
Para realizar el encaje es necesario introducir las piezas con un leve giro y no frontalmente. Por este sistema se permite una entrada y salida fácil, siendo en cambio muy difícil el desensamblaje accidental aplicando simplemente tensión.
Con este sistema, y después de muchos cambios, modificaciones y dolores de cabeza, plantamos las bases de “Tiny World”.
Seguimos trabajando en ello y aumentando el repertorio de piezas.
¡Permaneced atentos!
Versión online de LibreBORME
Con motivo de la evaluación del Concurso Universitario de Software Libre, esta última semana he estado trabajando en montar una versión de LibreBORME en producción y en darle una capa de pintura.
Para los impacientes: ya se puede acceder a través de https://beta.libreborme.net.
Como su dominio indica, es una versión de pruebas, por lo que fallará de vez en cuando, sus URLs cambiarán, algunas veces contendrá más datos y otras menos porque limpiaré la BD para seguir haciendo pruebas...
Tenlo en cuenta si la usas. De momento no hace falta que se reporten los bugs.
En cuanto a cambios significativos lo más novedoso es que gracias a la sugerencia de mi tutor del proyecto, he empezado a usar MongoDB para almacenar los datos, que viene muy bien ya que la estructura de un BORME se ajusta más al concepto de documento en Mongo que al de una tabla relacional SQL.
En esta primera versión online ya hay algunos miles de datos para empezar a jugar. Se pueden buscar empresas, ver en qué BORMEs aparece y sus actos mercantiles. También es posible buscar nombres de persona y de la misma manera localizar en qué BORMEs aparece y obtener un listado de sociedades relacionadas.
La página principal se carga cada vez con un listado aleatorio de empresas/personas a modo de ejemplo:
Ahora borme_parser es un paquete que importo en Python y que contiene todo lo necesario para procesar BORMEs. Cuando sea estable lo subiré a PyPI para que lo puedan reutilizar fácilmente otros proyectos que analicen BORMEs.
También he comenzado a usar los issues de GitHub:
borme_parserEl paquete borme_parser contiene un conjunto de herramientas que automatiza la obtención y el procesamiento de BORMEs. El proceso ahora es semi-automático (hay que lanzar los scripts uno a uno).
Los procesos que borme_parser automatiza son:
- Ir a la web del BORME y obtener los BORMES del último día
- Descargar todos los PDFs del día
- Recortar los PDFs para obtener otros PDFs con la región que nos interesa (quita los márgenes)
- Conversión de PDF a texto y limpieza del texto que suele contener caracteres extraños
- Reconocer en el texto los actos inscritos y en ellos los nombres de las entidades que nos interesan (empresas y personas principalmente) y generar un archivo CSV a partir de ellos
Para el que lo nunca haya visto, un BORME tiene el siguiente aspecto:
Detalles técnicos: para recortar PDFs uso PyPDF y para convertir los PDFs recortados a texto uso pdfminer. ¿Por qué dos distintos? Porque cada uno me ha dado mejores resultados en esa tarea concreta.
Para las otras dos secciones del BORME que sí publican en XML, la idea es usar XML Schema para que los parsers sean más flexibles y tolerantes a futuros cambios en la estructura.
Como anécdota, para pulir el parser me hice un script para comparar los resultados de dos parsers y ver así si los últimos cambios realmente mejoraban o empeoraban el resultado esperado.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16#!/bin/bash # ./parseandcompare.sh txt2/BORME-A-2015-27-07.pdf-cropped.pdf.1.txt.clean.txt echo $1 ./parserText2CSV4c.py $1 csv4=csv/$(basename $1).4c.plain diff -u0 $2 $csv4|pygmentize -l diff -f html -O full -o file_diff14.html echo 'Comparando' echo $2 echo $csv4 ls -l $2 $csv4 chromium-browser ./file_diff14.html &Esto genera un archivo html con las diferencias así:
En definitiva, los parsers funcionan, aunque tienen aún fallos y queda pulirlos bien. Tengo muchas ideas que quiero probar para mejorarlos. Más adelante dedicaré una entrada solo para ellos.
Datos importadosEn esta beta he cargado los datos disponibles hasta el 24 de marzo de 2015.
Algunos datos a modo de estadística:
Los PDF de la Sección Primera descargados (hasta el 24 de marzo) son en total 1609 archivos que pesan 372MB. Una vez recortados pesan 245MB y pasados a texto y aplicando el filtro de limpieza de caracteres raros, ya se quedan 52MB y finalmente los datos útiles en CSV son 40MB.
Importar los datos de 2015 en LibreBORME fue «tan sencillo» como ejecutar:
cd borme_parser ./getAllBormeXML.py 20150101 ./getPDFfromXML.py 20150101 ./crop_borme.py pdf ./parserPDF.py pdfcrop ./cleanText.py txt ./parserText2CSV4c.py txt2 ./manage.py importbormecsv borme_parser/csv/*.csvAlgunos tiempos de cada script, en negrita los más significativos:
Conversión de PDF a texto: 44 minutos
Limpieza del texto: 3 segundos
Generación de los CSV a partir de los textos: 29 segundos
Importación en Mongo: más de 8 horas
El proceso de importación de estos 40MB de CSV tardó más de 8 horas, algo que sin saber apenas nada de Mongo me parece excesivo y que tendré que investigar. Lo más lógico sería generar e importar directamente JSON en lugar de CSV, pero el motivo de porqué uso CSV es porque fue lo primero que se me ocurrió cuando aún no sabía que iba a usar MongoDB.
En total se han incorporado a la base de datos 124168 registros, identificándose 104800 empresas y 34496 personas.
Sin embargo a día 24 de marzo había 124879 registros, por lo que en 711 (0,57%) el parser falló y no consiguió importarlos.
¡Seguimos!