Tutorial de programación. APIs de Microsoft Flight Simulator X. C++

Bien, este simulador nos proporciona unas APIs (Application Programming Interface) que nos permiten crear programas que se comuniquen con el simulador. Con esto podemos tanto como leer datos del simulador como modificarlos. Estas APIs vienen incluidas en la versión Deluxe del juego y recomiendo para usarlas el IDE de Microsoft, el Visual C++, por la simple razón de que configurar ahí las librerías para empezar a programar es muy simple, si puedes configurarlo todo en el IDE que más te guste, bien por ti.

Lo que se instala con las APIs es el SDK (Standard Development Kit), que incluye la documentación, ejemplos, y mucho más además de las librerías. Lo que haremos aquí será ir sobre un ejemplo.

Lo primero es crear un proyecto, del tipo Aplicación de Consola Win32. En la carpeta donde se instalan las APIs debes encontrar el archivo SimConnect.h y SimConnect.lib, y copiarlos en la carpeta del proyecto, en el mismo directorio en el que se creen los archivos de fuente principales. En mi caso llamé al proyecto VORdriver por ser el dispotivo VOR el primero que iba a simular, así que estos archivos de fuente son VORdriver.cpp y VORdriver.h.

Después debemos configurar el IDE para que el linker vincule las librerías de SimConnect a nuestro proyecto, para eso, en el IDE, vamos a: Proyecto/Propiedades de proyecto. Y en el menú de la izquierda: Propiedades de configuración/Vinculador/Línea de comandos. En opciones adicionales escribimos SimConnect.lib, y ya está listo.

Ya podemos empezar a programar.

El programa consiste básicamente en una serie de funciones y estructuras clave. La función clave es la función CALLBACK, que es llamada cada vez que el simulador o algún otro cliente informan de un evento, o de la llegada de algún tipo de datos.

Los eventos se encuentran en la documentación de la SDK, en la sección EVENT IDs. Uno que nos interesará mucho será “6 Hz”. Como su nombre indica, lo único que hace es saltar 6 veces por segundo. Esto nos es muy útil si por ejemplo necesitamos información del simulador continuamente, ya que podemos pedir información cada vez que salte este evento, y 6 herzios es una buena frecuencia (es aproximadamente la frecuencia de refresco del estado de los joysticks, según esa misma documentación).

Bien, lo que haremos será recorrer un ejemplo en el que mediante ese evento pediremos una serie de datos al simulador. Los datos serán, por tenerlos ya hecho, el nombre del avión y la desviación de las agujas de los indicadores VOR. Lo primero que haremos será crear una estructura con esos datos:

#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#include <Windows.h>
#include "SimConnect.h"
#include <string>
#include <sstream>
#include <iostream>
using namespace std;

int     quit = 0;
HANDLE  hSimConnect = NULL;

struct Struct1
{
    char    title[256];
    double  cdi1;
    double  cdi2;
	double  gsi1;
};

Las dos cdi son la “course deviation indicator”, la 1 del primer indicador y la 2 del segundo. gsi1 es el “glide slope indicator” del primer indicador (el segundo no tiene). Es importante definir como “double” todas las variables que devuelvan un resultado numérico, porque siempre se devuelven así, aunque los únicos valores posibles sean 0 ó 1, y si no puedes obtener resultados extraños.

Lo siguiente que haremos será crear varias enumeraciones:

static enum GROUP_ID{
	GROUP0,
};

static enum EVENT_ID{
	CONT,
};

static enum DATA_DEFINE_ID {
    DEFINITION_1,
};

static enum DATA_REQUEST_ID {
    REQUEST_1,
};

Las explico. La primera no es muy relevante en este caso. Sirve para poder crear un sistema de prioridades entre grupos de clientes a los que nos conectemos en el caso de hacerlo. En este caso sólo nos conectamos al simulador, así que no lo usaremos. Sin embargo en otros casos nos podría interesar crear más de un programa que se comunique con el simulador y que además esos se comuniquen entre ellos, por ejemplo lanzando eventos (también podemos definir eventos y lanzarlos, además de recibir los del simulador).

La segunda sí es importante, nos sirve para definir los eventos que usaremos, en este caso sólo 1, el CONT, que se corresponderá con el de 6 Hz.

La tercera la usaremos porque las definiciones posteriores se realizan agrupadas bajo un índice y este es el que usaremos, de nuevo, sólo tenemos una. La cuarta nos servirá para pedir datos al simulador, por la misma razón.

Ahora definimos la función CALLBACK:

void CALLBACK dmeDispatch(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext) {
	HRESULT hr;

	switch (pData->dwID) {
		case SIMCONNECT_RECV_ID_EVENT:
		{
			SIMCONNECT_RECV_EVENT *evt = (SIMCONNECT_RECV_EVENT*)pData;
			switch(evt->uEventID) {
				case CONT:
					//Pedir datos
					hr = SimConnect_RequestDataOnSimObjectType(hSimConnect, REQUEST_1, DEFINITION_1, 0, SIMCONNECT_SIMOBJECT_TYPE_USER);
				break;
			}
			break;
		}

		case SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE:
		{
			SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE *pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE*)pData;
			switch(pObjData->dwRequestID)
            {
                case REQUEST_1:
                {
                    DWORD ObjectID = pObjData->dwObjectID;
                    Struct1 *pS = (Struct1*)&pObjData->dwData;
                    if (SUCCEEDED(StringCbLengthA(&pS->title[0], sizeof(pS->title), NULL))) // security check
                    {
                                                cout << "Title: " << pS->title << endl;
						cout << "CDI: " << pS->cdi1 << endl << "GSI: " << pS->gsi1 << endl;
						cout << "CDI2: " << pS->cdi2 << endl;
                    } 
					
                    break;
                }

                default:
                   break;
            }
            break;
			break;
		}
	}
}

Como ves a la función se le pasa como argumento un puntero a una estructura del tipo SIMCONNECT_RECV. Esta estructura tiene un miembro llamado dwId que nos permite decidir que tipo de datos nos está llegando. En este caso sólo separamos entre dos.

El primero es SIMCONNECT_RECV_ID_EVENT, que nos notifica que ha saltado algún tipo de evento. El segundo es SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE, que como su nombre indica supone la llegada de datos sobre algún objeto del simulador, en este caso el avión.

En el caso de que llegue un evento lo que hacemos es ver qué evento es el que ha saltado. Eso lo hacemos mediante otro switch. En este caso sólo pedimos un evento (luego veremos cómo se registran para que se nos notifique de ellos), así que sólo puede ser un evento, pero lo hacemos así porque en un futuro es probable que queramos usar más eventos.

Después de hacerle casting al puntero de la estructura, miramos el miembro uEventId para ver que evento es, y después de verificar que se trata de CONT, hacemos lo que queremos hacer, en este caso pedir al simulador que nos devuelva una estructura con los datos que queremos. La función asocia la orden al “número” REQUEST1, de manera que podamos filtrarlo luego, y pide los datos asociados a DEFINITION1.

En la segunda parte de la función verificamos que el objeto SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE es el correspondiente a REQUEST1. Lo que contiene esta estructura es un puntero a otra estructura copia de la que hemos definido nosotros, con los datos del simulador en el momento de pedirlos. Podemos acudir a ellos (mediante el puntero pS), y hacer lo que queramos, en este caso los imprimimos en pantalla.

Eso es todo lo concerniente a la función CALLBACK. Ahora veamos la función main, donde inicializamos todo y hacemos las asociaciones.

int _tmain(int argc, _TCHAR* argv[])
{
	HRESULT hr;

    if (SUCCEEDED(SimConnect_Open(&hSimConnect, "VORdriver", NULL, 0, 0, 0)))
    {
        printf("\nConnected to Flight Simulator!");   
        
        // Set up the data definition, but do not yet do anything with it
        hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Title", NULL, SIMCONNECT_DATATYPE_STRING256);
        hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "NAV CDI:1", "number");
        hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "NAV CDI:2", "number");
        hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "NAV GSI:1", "number");

        hr = SimConnect_SetNotificationGroupPriority(hSimConnect, GROUP0, SIMCONNECT_GROUP_PRIORITY_HIGHEST);
	hr = SimConnect_SubscribeToSystemEvent(hSimConnect, CONT, "6Hz");

        while( 1 )
        {
            SimConnect_CallDispatch(hSimConnect, dmeDispatch, NULL);
            Sleep(1);
        } 
        hr = SimConnect_Close(hSimConnect);
    }

	return 0;
}

Lo primero que hacemos es definir una variable del tipo HRESULT que nos permite leer lo que devuelven las funciones de las API. Después intentamos conectarnos al simulador dentro del if mediante la función SimConnect_Open(), la función nos pide una variable del tipo HANDLE y un nombre.

Si consigue conectarse, empezamos a hacer asociaciones. La función SimConnect_AddToDataDefinition nos permite asociar datos a DEFINITION1, el nombre de los datos está en la sección “Simulation Variables” de la documentación del SDK. En nuestro caso son TITLE, NAV CDI:X y NAV GSI:1.

Después la función SimConnect_SetNotificationGroupPriority() define las prioridades comentadas antes, aunque se puede quitar puesto que sólo nos conectamos al simulador.

Por último la función SimConnect_SubscribeToSystemEvent() nos permite decir que eventos queremos que nos notifiquen. Hay otra función SimConnect_MapClientEventToSimEvent(), que permite hacer que salte uno de nuestros eventos cuando salte el del simulador, pero me ha dado problemas.

Pues eso es todo, por último creamos un bucle infinito y usamos la función SimConnect_CallDispatch() continuamente para ver si hay algo que hacer.

Ahora ejecuta el simulador, abre un vuelo, y después compila y ejecuta el código. La consola debería mostrar el texto con el valor de las agujas de los indicador VOR, a una frecuencia de 6 veces por segundo.

Hasta aquí el artículo dedicado exclusivamente a las API, en la documentación hay un montón de ejemplos que me han sido muy útiles. Además en los siguientes artículos en los que hable de cacharros en concreto, también mostraré el código que uso para manejarlos, y lo explicaré.

Un saludo.

Publicado en Manuales, Tutoriales | Etiquetado , , , , , , , , , | Deja un comentario

Simulación de vuelo. Indicador DME casero.

Bien, este es el primer artículo sobre esto. Cuando empecé, escogí el indicador DME como primera creación por su simplicidad. Consiste en dos displays de tres cifras cada uno, y un interruptor. Este es el pantallazo del Microsoft Flight Simulator X (A partir de ahora FSX):

DMEBien, como vemos tiene varios interruptores y un dial giratorio, sin embargo el FSX sólo nos deja configurar uno de los interruptores, el que itnercambia entre R1 y R2, y el resto está de decoración, así que en mi modelo sólo hice el interruptor que funciona. Como ya dije en un artículo anterior, este DME no será el que use al final. En el final sí incorporaré todos los diales porque tengo claro que en algún momento me pasaré del FSX al X-Plane, que a diferencia del primero continua en producción, y este último si incorpora el resto de cosas.

Bueno, describo un poco el cacharro. En un avión por lo general tenemos cuatro canales de radio. Dos de ellos están dedicados a comunicaciones (COM1 y COM2), y los otros dos a navegación (NAV1 y NAV2). Estos dos últimos los podemos sintonizar a unas estaciones llamadas estaciones VOR (VHF Omnidirectional Radio range, o Radiofaro Omnidirección VHF), que entre otras cosas nos permite conocer nuestra posición relativa con respecto a radiales que salgan de la estación. Pues bien, este indicador DME (Distance Measurement Equipment), nos da la distancia a la que estamos de lo que tengamos sintonizado en las NAV#, y la velocidad relativa con respecto a ellas. El interruptor nos permite cambiar entre los canales NAV1 y NAV2.

La construcción es de la siguiente manera: Tenemos 6 displays de siete segmentos de ánodo común, son en concreto estos: http://dx.com/es/p/fj5101bh-10-pin-7-segments-red-led-display-common-anode-10-pcs-151060

Estos displays tienen 10 pines, dos de ellos son el ánodo común de los 8 LEDs, y los otros 8 pines son uno para cada LED. Para iluminar cada uno hay que poner voltaje alto en el ánodo y tierra en el pin correspondiente al segmento. Como son 6 displays, tenemos 6·9=54 pines, y la placa arduino no tiene tantos. Podríamos usar registros electrónicos para disminuir el número de pines necesarios, pero en este caso yo lo hice de otra manera: multiplexing.

Esto consiste en lo siguiente. Conectamos todos los pines correspondientes al primer segmento juntos, todos los correpondientes al segundo segmento juntos, y así con todos, de manera que tenemos los ánodos de cada display suelto, y el resto de pines unidos entre si, de la siguiente manera:

Esta foto la he sacado de por ahí, y lo hacen con cuatro, pero lo puedes hacer con los que quieras, el resutado final es que los ánodos están conectados cada uno de ellos a un pin que podemos controlar, y luego los pines correspondientes a cada segmento, todos juntos, a otro pin. En este caso el número de pines a usar es 8+6=14. Y eso sí lo tenemos. Por cierto, que yo no uso transistores porque la placa da corriente suficiente, lo hice más simple. Seguramente en el proyecto final lo haga como en la foto.

Si queremos mostrar un número en los tres primeros dígitos, por ejemplo el 123, lo que hacemos es lo siguiente:

Ponemos voltaje alto al primer dígito y voltaje bajo el resto, de este modo sólo se enciende el primer dígito, y el resto permanecen apagados. Ahora usamos los pines de los segmentos para mostrar el número 1. Como el único ánodo con voltaje alto es el primero, sólo se mostrará el número 1 en el primero de ellos. Ahora esperamos una cantidad de tiempo. A continuación apagamos el primer dígito y encendemos el segundo, y mostramos el número 2. Esperamos la misma cantidad de tiempo. Apagamos el segundo dígito, encendemos el tercero y mostramos el número 3, y esperamos la misma cantidad de tiempo.

Tendremos la siguiente secuencia:

multiplexing

El secreto para que se muestren los 3 al mismo tiempo está en el tiempo que esperamos entre que mostramos un número y el siguiente. Si este tiempo es lo suficientemente pequeño, por ejemplo 5 mili segundos funciona muy bien con 3 dígitos. Entonces el cambio se produce tan rápido que no somos capaces de percibirlo y da la impresión de que se muestran los 3 números al mismo tiempo.

En el DME eso es lo que hacemos. La circuitería no tiene ningún misterio. Hacerlo en una placa perforada fue un verdadero coñazo y me asombra que no me equivocase al soldar ninguna de las conexiones, pero de milagro, funciona. El interruptor es un circuito simple de interruptor, aquí lo tenéis hecho en 5 segundos con el Paint:

interruptor

No recuerdo exactamente si conecté el interruptor al pin A0, pero vamos, que cualquiera vale. Aquí tenéis todo el circuito en una breadboard, la tercera lo muestra conectado al simulador y funcionando:

20130602_00220130602_00120130602_004

Aquí dejo más fotos del montaje donde se puede ver el multiplexing soldado en las dos placas por separado, y conectado para probarlo al simulador:

20130603_00220130606_001 20130606_002 20130612_005

20130612_006 20130616_004 20130623_001 20130623_002

Vale, ahora sólo queda el código. Hay dos programas de los que depende el funcionamiento de todo lo que hagamos. Uno de ellos es el que use la placa Arduino, y el otro es el que se ejecuta en el ordenador y funciona como mensajero entre el simulador y la placa.

Como en el proyecto final habrá muchos cacharros y el procesador de la placa es muy lento (16 MHz, contra los más de 3GHz de mi portátil), intentaremos liberar todo el trabajo que podamos de la placa y haremos que todos los cálculos se realicen en el ordenador. Eso significa que la placa lo único que hará será recibir datos, leerlos e imprimirlos. En este caso no habrá mucha diferencia, pero en otros sí, y la diferencia será mayor cuando queramos poner en marcha todo a la vez. El código de la placa Arduino es el siguiente:

http://pastebin.com/C3qDaaik

Siento no haberlo comentado pero lo explico un poco por aquí: La comunicación entre placa y ordenador es una comunicación Serial por usb. Lo que hace el programa del ordenador es mandar cadenas de caracteres ASCII. Como la placa recibe dos tipos de datos (velocidad y distancia) usaremos delimitadores para poder distinguirlos. En este caso, por ser un proyecto reciclado de por ahí, los delimitadores son ‘<‘ y ‘>’ para la distancia, y ‘S’ y ‘s’ para la velocidad. La placa recibirá cadenas del tipo: “<056>S100s”. La función processInput(), junto con processNumber() y processSpeed() realizan ese trabajo en las dos primeras lineas del bucle principal loop().

La variable “negative” se usa para diferenciar de cuando hay señal DME, y de cuando no. En este último caso se deben mostrar tres guiones en cada display. Eso es lo que hace el resto de la función loop(): Si la variable negative es falsa, entonces procede al multiplexing, si es verdadera, muestra los guiones.

El código del ordenador lo publicaré en un artículo distinto como una guía más general orientada a usar las APIs del FSX.

Hasta otra.

Publicado en Noticias | 2 comentarios

Hardware de simulación de vuelo made in casa

Como ya publiqué aquí hace tiempo que me interesé por los simuladores de vuelo, y hace ya tiempo también que me di cuenta de que jugar con teclado y ratón a estos simuladores no sólo hace más complicado volar, sino que lo hace mucho más aburrido, y muy poco realista. Sobre todo cuando tienes que pausar el juego cada vez que quieres tocar algo del panel de la cabina.

Es por eso que empecé a buscar hardware para el simulador, que por cierto el que uso ahora mismo es el Microsoft Flight Simulator X.

Lo primero que adquirí fue un pack con Yoke y Throttle Quadrant de la casa Saitek:

Yoke + Throttle quadrant

Lo encontré en Amazon relativamente barato y lo compré. El Yoke (timón) es bastante bueno y parece bastante sólido. No se puede decir lo mismo de las palancas, pero funcionan perfectamente.

Mi siguiente compra fue un panel de piloto automático, flaps y compensador de cabeceo, de la misma marca:

De este se puede decir lo mismo, funciona muy bien y hace lo que ofrece. De momento eso es todo lo que tengo. Lo que me queda por comprar son pedales y un segundo throttle quadrant para un avión bimotor.

Ahora bien, yo quiero construir la cabina entera, pero el resto de cosas, y ese es e objetivo de este artículo de los siguientes, las construiré yo mismo. Iré sacando artículos con cada cosa conforme las voy construyendo y explicaré cómo lo he hecho. En líneas generales, lo que sea electrónica lo diseñaré con Eagle y se lo encargaré a alguna empresa que fabrique placas impresas. Lo que sea más mecánica lo diseño con Blender y lo imprimo en 3D a través de Shapeways. De estos ya he empezado y tengo lo siguiente:

13090005Son, de izquierda a derecha: El coordinador de giro, el velocímetro, el indicador VOR, el indicador de velocidad vertical y el indicador de actitud. Este último necesita muchos retoques pero el resto (a falta de gráficos), funcionan perfectamente.

Con respecto al funcionamiento, estos son todos los que tienen movimientos acotados y funcionan mediante servomotores (muy baratos comprados en DealExtreme por menos de 2€ cada uno). Uso una placa Arduino Uno R3 para manejar los motores, y el Microsoft Flight Simulator X ofrece unas APIs para C++ muy fáciles de usar, que es la manera en que se intercambian datos entre simulador y placa arduino.

Hay otro componente del que no hay foto, pero mañana intentaré publicar alguna, es un indicador DME (un prototipo), hecho sobre una placa perforada. Ha quedado muy sucio (aunque funciona) y lo sustituiré por una PCB bien hecha, aun así lo enseñaré y explicaré cómo lo he hecho. Iré publicando artículos sobre cada uno en el orden en el que los he hecho:

  1. Indicador DME.
  2. Indicador VOR.
  3. Indicador de velocidad vertical (VSI) y veocímetro (son iguales).
  4. Coordinador de giro.
  5. Indicador de actitud.
Publicado en Manuales, Noticias, Tutoriales | Etiquetado , , , | 2 comentarios

Teoría de grupos y el cubo de Rubik

Vamos allá.

La teoría de grupos es una rama de las matemáticas que pertenece al marco más general del álgebra abstracta. En el álgebra abstracta se estudian estructuras matemáticas de cualquier tipo de la forma más general posible. El hecho de que el estudio sea tan general y abstracto es que podemos aplicarlo después a cualquier caso concreto que obedezca a alguna de esas estructuras. Esto permite ver similitudes entre cosas matemáticas que, a priori, parecen completamente distintas e independientes.

Seguir leyendo

Publicado en Manuales, Matemáticas, Tutoriales | Etiquetado , , , , , , , , , | Deja un comentario

Curva de carga y descarga de un condensador con Arduino

Bueno, es la primera vez que publico algo sobre electrónica. Lo que vamos a hacer es visualizar la curva de carga y descarga de un condensador con la ayuda de una placa Arduino (en mi caso la Arduino Uno). Si has estudiado algo de electromagnetismo estarás bastante harto de hacer problemas de condensadores que se cargan, que se descargan, que si les metemos un dieléctrico, que si el dieléctrico sólo ocupa un cuarto, etc…

También es práctica obligada de laboratorio el visualizar estas curvas, normalmente con un osciloscopio. El problema de esto que los osciloscopios cuestan alrededor de 1000€, y las placas Arduino entre 15€ y 30€, así que para hacerlo en casa, casi que mejor esto segundo. Evidentemente nuestra placa no es tan precisa como un osciloscopio, pero podremos tener una imagen cualitativa muy buena, e incluso con un poco de cuidado, podremos analizar cuantitativamente los resultados.

Seguir leyendo

Publicado en Física, Manuales, Tutoriales | Etiquetado , , , , , | 1 Comentario

Acertijo matemático. Problema de los suministros

Es muy conocido el siguiente acertijo del que voy a hablar en esta entrada, conocido como problema de los suministros:

Dado el siguiente diagrama:

Acertijo

Acertijo

Hay que intentar unir los tres puntos de arriba con los tres de abajo mediante lineas (rectas o curvas) de manera que cada vector de arriba esté conectado con todos los de abajo y viceversa, y de manera que las lineas no se corten. Es decir, hay que hacer la siguiente imagen:

¿Puedes?

¿Puedes?

Pero de manera que las lineas no se corten entre si. Inténtalo, y luego sigue leyendo para saber la solución.

Seguir leyendo

Publicado en Matemáticas | Etiquetado , , , , , , , , , , , , , , | Deja un comentario

DUO

Antes que todo, creo que la gente ya sólo pasa por aquí desde links de Google, ya que hace un montón que no publico. La verdad es que me gusta mucho llevar un blog, pero lamentablemente (o afortunadamente), tengo mi tiempo muy ocupado con estudios que también disfruto y este blog queda muy atrás. Me gustaría empezar a publicar curiosidades de matemáticas y física, que son lo mio, y de informática más teórica que también me encanta, y retomar así el camino que el blog parecía estar llevando durante los últimos posts antes de empezar el curso.

Empezamos. Creo que publiqué hace tiempo (la verdad es que no me acuerdo y no he mirado las entradas viejas) un post sobre un proyecto que hice en Linux para construir una mesa táctil casera, y programar yo mismo los drivers. El proyecto era muy simple, era simplemente una caja de cartón con una webcam en el fondo y una pantalla traslúcida arriba. La webcam recogía la imágen de la pantalla (si ponías un dedo se veía una sombra), y mediante software recogíamos las imágenes de la webcam, las tratábamos, y aislábamos los puntos, cosa que sí se explicó en varios posts sobre componentes conexas de grafos: 1, 2 y 3.

El software es muy rudimentario, además al reinstalar Linux incluso volviendo a configurar todas las librerías que usaba (opencv y sdl), no consigo volverlo a compilar. Una lástima porque funcionaba bien y cumplía su cometido.

El caso es que después de aquello me metí más en el mundillo, que resultó ser grande, y descubrí NuiGroup, una gente que desarrolló, entre otras muchas cosas, un programa genérico de reconocimiento de puntos, que permitía registrarlos y mandarlos mediante sockets (cosa que también había programado yo). Sobra decir, claro, que el suyo funcionaba, y funciona, mucho mejor. El programa se llama CCV (Computer Core Vision), y es gratuito, open-source, y multiplataforma, y es muy interesante.

La última de Nui, de una división/subgrupo/compañeros/grupo independiente llamado CL, es el producto DUO. Consiste en un par de cámaras que registran el movimiento, ya no sólo de la imagen, sino de la profundidad. Tienen una demo en vídeo increíble y parece que la precisión es enorme. La información del producto está aquí, en su página principal.

Lo malo es que el producto está en fase desarrollo. han lanzado un proyecto de Kickstarter para terminar de producirlo y si les ayudas consigues un DUO a un precio más barato que el que será su precio final. Pro si alguien no lo conoce, Kickstarter es una plataforma para conseguir fondos para un proyecto. Los fondos los pagan los visitantes de la página que quieran colaborar en el proyecto, y lo bueno es que tú dices lo que quieres dar y eso se va sumando al fondo, si al final no han conseguido dinero suficiente, no te cobran, y no te cobran hasta que el proyecto no ha terminado su fase de kickstarter y ha conseguido el suficiente dinero, lo que da bastante garantía.

Aquí tenéis la página de Kickstarter del proyecto DUO. A la derecha podéis ver los rewards (premios), que conseguís según el dinero que donéis al proyecto. Yo ya he puesto mis 110$ que equivalen a un DUO para hacerlo en casa. Por 140$ lo tenéis ensamblado, y si no, podéis donar el dinero que queráis, desde 1$ para arriba. Echadle un vistazo. A mi ya se me ocurren mil cosas que programarle. Mirad la página para más información

Publicado en Noticias | Etiquetado , | 4 comentarios