He creado una clase llamada BarraInfo para que podais añadir a vuestros proyectos de Processing. La clase sirve para crear barras de información, como las que habeis visto en la telemetría para mostrar el PWM de los motores o el nivel de la batería.
La ventaja de usar esta clase (y cualquier otra) es que os evitais tener que crear el código de cero porque ya está hecho, podeis usarla en todos los proyectos de Processing que hagais, podeis tener varias barras de información en la pantalla y se puede configurar a medida.
A continuación os pongo el código fuente de la clase:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
class BarraInfo { float inicio; // primer valor del rango float fin; // último valor del rango color linea; // color del texto de los valores de referencia y las muescas color barra; // color de la barra int x; // posición x del conjunto int y; // posición y del conjunto int anchura; // anchura de las muescas y de la barra int altura; // altura del conjunto int pasoLinea; // cada cuantos píxeles se dibuja una muesca int pasoNumero; // cada cuantos píxeles se dibuja un valor de referencia del rango PFont fuente; // fuente con la que se dibuja el texto de los valores de referencia int recorteX; // ajuste de la posición X del texto de los valores de referencia int recorteY; // ajuste de la posición Y del texto de los valores de referencia int digitos; // Número de digitos que aparecerán en el texto de los valores de referencia int decimales; // Número de decimales que aparecerán en el texto de los valores de referencia float valor; // Valor real BarraInfo() { valor = 0; } void dibuja() { int indice; int longitud; stroke(linea); fill(linea); text(nfs(map(y, y, y + altura, fin, inicio), digitos, decimales), x - recorteX, y + recorteY - pasoLinea); text(nfs(map(y + altura, y, y + altura, fin, inicio), digitos, decimales), x - recorteX, y + altura + recorteY - pasoLinea); for(indice = y; indice <= y + altura; indice++) { if(indice % pasoLinea == 0) { line(x, indice, x + anchura, indice); } if(indice % pasoNumero == 0) { text(nfs(map(indice, y, y + altura, fin, inicio), digitos, decimales), x - recorteX, indice + recorteY - pasoLinea); } } stroke(barra); fill(barra); longitud = int(map(valor, inicio, fin, 0, altura)); rect(x + anchura * 2, y + altura - longitud, anchura, longitud); } } |
Para usarla os voy a poner un ejemplo de cómo mostrar el PWM asignado a un motor.
Lo primero es copiar el código fuente que he puesto más arriba en vuestro proyecto, preferentemente al final.
Lo segundo es crear una variable global del tipo BarraInfo.
1 |
BarraInfo pwm; |
Lo tercero es instanciar la clase para crear un objeto en el método setup de vuestro sketch.
1 |
pwm = new BarraInfo(); |
Después, y dentro del mismo método setup inicializamos las variables de la clase. Dado que las variables de las clases de Processing son públicas y no se admiten variables de tipo privado, he preferido acceder a ellas directamente sin métodos get/set:
Establecemos el valor de inicio y final que podrá tener la barra, en el PWM es de 0 a 255, en una batería Lipo sería de 0 a 8,4.
1 2 |
pwm.inicio = 0; pwm.fin = 255; |
Establecemos el color de las lineas (que comprende las muescas y el texto asociado a ellas) y el color de la barra.
1 2 |
pwm.linea = color(0, 255, 255); pwm.barra = color(0, 0, 255); |
Establecemos la posición x e y de nuestra ventana donde se mostrará la barra de información.
1 2 |
pwm.x = 300; pwm.y = 100; |
Establecemos la anchura de las muescas y de la barra (cada una) y la altura del conjunto.
1 2 |
pwm.anchura = 10; pwm.altura = 150; |
Establecemos cada cuantos píxeles se dibuja una muesca y cada cuantos píxeles se muestra un número de referencia.
1 2 |
pwm.pasoLinea = 5; pwm.pasoNumero = 25; |
Establecemos la fuente que previamente habremos creado en el menú Tools/Create Font… de Processing y la desplazamos en su eje x e y para que encaje bien en las muescas.
1 2 3 |
pwm.fuente = loadFont("ArialMT-12.vlw"); pwm.recorteX = 30; pwm.recorteY = 10; |
Establecemos el número mínimo de enteros que apareceran (rellenando con ceros por la izquierda si no llega) y el número de decimales (-1 si no queremos que salgan) de los números de referencia.
1 2 |
pwm.digitos = 3; pwm.decimales = -1; |
Finalmente en el método draw se debe establecer el valor que debe tener la barra y pintarlo. He puesto un random para que pueda apreciar el movimiento.
1 2 |
pwm.valor = random(255); pwm.dibuja(); |
Así es como quedaría el código fuente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
BarraInfo pwm; void setup() { size(600, 600); pwm = new BarraInfo(); pwm.inicio = 0; pwm.fin = 255; pwm.linea = color(0, 255, 255); pwm.barra = color(0, 0, 255); pwm.x = 300; pwm.y = 100; pwm.anchura = 10; pwm.altura = 150; pwm.pasoLinea = 5; pwm.pasoNumero = 25; pwm.fuente = loadFont("ArialMT-12.vlw"); pwm.recorteX = 30; pwm.recorteY = 10; pwm.digitos = 3; pwm.decimales = -1; } void draw() { background(0); pwm.valor = random(255); pwm.dibuja(); } class BarraInfo { float inicio; // primer valor del rango float fin; // último valor del rango color linea; // color del texto de los valores de referencia y las muescas color barra; // color de la barra int x; // posición x del conjunto int y; // posición y del conjunto int anchura; // anchura de las muescas y de la barra int altura; // altura del conjunto int pasoLinea; // cada cuantos píxeles se dibuja una muesca int pasoNumero; // cada cuantos píxeles se dibuja un valor de referencia del rango PFont fuente; // fuente con la que se dibuja el texto de los valores de referencia int recorteX; // ajuste de la posición X del texto de los valores de referencia int recorteY; // ajuste de la posición Y del texto de los valores de referencia int digitos; // Número de digitos que aparecerán en el texto de los valores de referencia int decimales; // Número de decimales que aparecerán en el texto de los valores de referencia float valor; // Valor real BarraInfo() { valor = 0; } void dibuja() { int indice; int longitud; stroke(linea); fill(linea); text(nfs(map(y, y, y + altura, fin, inicio), digitos, decimales), x - recorteX, y + recorteY - pasoLinea); text(nfs(map(y + altura, y, y + altura, fin, inicio), digitos, decimales), x - recorteX, y + altura + recorteY - pasoLinea); for(indice = y; indice <= y + altura; indice++) { if(indice % pasoLinea == 0) { line(x, indice, x + anchura, indice); } if(indice % pasoNumero == 0) { text(nfs(map(indice, y, y + altura, fin, inicio), digitos, decimales), x - recorteX, indice + recorteY - pasoLinea); } } stroke(barra); fill(barra); longitud = int(map(valor, inicio, fin, 0, altura)); rect(x + anchura * 2, y + altura - longitud, anchura, longitud); } } |
Y así el resultado:
Me gusta como te ha quedado, y la idea a seguir de ir creando objetos individuales para cada elemento hardware que reutilizar en distintos interfaz puede funcionar. Integrar elementos físicos hardware en el pc.
Por cierto le has sumado un voltio de más a la lipo 🙂
Buen primer objeto y entrada, me parece muy atractivo este proyecto.
Sólo quedarían dos clases por crear para parecerse a lo que tengo: la que te muestra los sensores sobre la linea y la que la te muestra el error y el PD en el tiempo.
Lo de la LiPo es porque las de 2 celdas se pueden cargar como máximo a ese valor (la carga máxima de una celda es de 4.2V).
Pronto tendremos nuestro sistema de telemetría made in C.I.R.E 🙂
Cierto lo de la lipo, no lo había pensado.
Tenemos que mirar bien que es lo que queremos medir con el interfaz en los velocistas, para poder comparar entre distintos ajustes, tengo en la mesa un montón de apuntes que mirarme del tema pero todavía no he sido capaz de empezar…
Lo primero que se me ocurre es un sumatorio de los valores absolutos de los errores para poder comparar entre ajustes, y valores máximos y mínimos, pero bueno ya hablaremos el tema en el foro que a Raúl le gustan estas cosas del control.
De momento voy a meter estas barras en mi ventana de processing y creo que les voy a añadir arriba un campo de texto, para poner por ejemplo «motor derecho», y abajo el valor numérico del gráfico.
La verdad es que se pueden medir multitud de parámetros (incluso unos dentro de otros).
Lo que comentas de los valores absolutos, como se puede crear un fichero desde Processing, luego se puede importar en una hoja de excel y ver lo resultados e incluso hacer gráficas. Lo bueno de la telemetría es que da igual que sea un velocista, un micromouse, un quadrator o o que sea, que siempre podrás obtener información de lo que está pasando en cada momento.
Chulísimo, este proyecto aportará mucha flexibilidad y como herramienta de ajuste o análisis la propuesta es estupenda ya es hora de que regulemos sin dar palos de ciego.
Excelente entrada.
waw, es bestial oscar, te has superado, enhorabuena
pero hay un problema…como haces que se interconecten unos con otros? podria via usb interconectarlos y probarlo?
saludos
Gracias a todos.
David, ¿a que te refieres con que interconecten?
si, por ejemplo, enchufar el robby al usb y al ordenador y poder medir los parametros internos como pwm de los motores, sensores analogicos…
Sería todo como comunicaciones serie.
El el robby haces que envié los parámetros por usb
En processing abres el puerto serie del usb, recibes los datos y los guardas en las variables de tu programa para que posteriormente se pinte.
En este artículo sería la variable valor donde tendrías que guardar el dato que has recibido del robby