[Smooth] [S-Curve]

132 views
Skip to first unread message

Democrito

unread,
Jun 6, 2020, 8:35:46 PM6/6/20
to FPGAwars: explorando el lado libre
Hola,

Estuve mirando formas de implementar "movimientos suaves" sin utilizar operaciones matemáticas complicadas y al final encontré una forma muy sencilla y discreta (digital) de hacerlo. Se trata de utilizar el algoritmo de Bresenham para circunferencias. Hay como mínimo dos formas de implementar ese algoritmo y he utilizado el mismo que usé como ejemplo en la pantalla Oled. Como decía, existen al menos dos algoritmos para circunferencias; una es por cuadrantes (como un pastel dividido en 4 partes iguales) y la otra es por octantes (como un pastel dividido en 8 partes iguales). Gráficamente usar el de octantes es más eficiente y rápido, porque hay que calcular menos y todo se repite. Pero para manejar motores me pareció más conveniente usar el de cuadrantes, y equivale a calcular un ángulo de 0 a 90 grados para un radio dado.

Nos olvidamos ahora de la parte gráfica y hagamos que un programa con este algoritmo nos muestre los números que salen para las coordenadas de los ejes X e Y. Veremos lo siguiente:

salida de datos bresenham para curvas.PNG


Al programa le doy como Radio el valor 16 (es arbitrario) y los valores de salida son los que se ven en la imagen donde la columna izquierda representa los valores del eje X y la de la derecha el eje Y. El programa está manipulado para que dé siempre números positivos usando la función ABS() para el eje X que es siempre negativo, y el Y no hay que hacer nada porque es siempre positivo.

Hemos de observar cómo en el eje X al comienzo se repiten valores, y lo mismo pasa en el eje Y pero hacia el final. Podemos comprobar que las sucesiones y repeticiones no son lineales, sino que se repite varias veces y cada vez se repite menos para que finalmente el resto de número (la mayoría) no se repitan.

El siguiente paso es tomar sólo los valores de salida del eje X y cuando termina, volvemos a ejecutar el programa pero sólo tomando los valores del eje Y; esto se puede hacer con un "for" que se ejecute dos veces y conmutar dicha salida (primero de X y luego de Y).

concatenacion de salida ejes x e y.PNG


Para verificar que realmente estamos haciendo "smooth movement" vamos a graficar esta salida de datos haciendo unas artimañas (para que no vuelva hacia atrás, sino que prosiga):

s.curve.PNG


Se ve un poco cutre pero es porque son sólo 29 puntos (14 del eje X y 15 del eje Y), pero se aprecia perfectamente que es una sigmoide.

Ahora vienen tres pasos cruciales, pero estas tres partes no son tan evidente. Si, como en el ejemplo, damos un valor de 14, nos saldrá 29 resultados cuando en realidad necesitamos 14.

Paso 1: Observamos si el valor de entrada (el radio) es par o impar para luego poner condiciones y así hacer corresponder, por ejemplo, si le doy una entrada de 14, me saque 14 pasos.
Paso 2: Hemos de dividir los dato de salida entre 2.
Paso 3: Cada paso mide un mismo tiempo. Si el número se repite se suman los tiempos de cada uno de ellos, pero sólo hay un paso (sin importar las veces que se repita). Es decir, que sólo cuando el número cambia de un paso al siguiente es cuando validamos ese paso.

Todo esto lo probé primero programando y una vez que conseguí que funcionase bien lo pasé a Verilog junto con otros módulos y me quedó así:

modulo de smooth movement.PNG

Este es el módulo principal, el cerebro que permite este tipo de movimiento. Tiene una entrada de 16 bits y siempre ha de ser números positivos.

El ICE que pongo como ejemplo es este:

Numerical_S-Curve.PNG

Se trata de ver a través de los leds cómo va contando y lo hace de la siguiente manera: Comienza contando lento, se va incrementando, después ya toma una velocidad de contaje rápido la mayor parte del tiempo y cuando se acerca al final vuelve a relantizarse de la misma forma que empezó (pero al revés).


Si alguien le apetece probarlo, lo único que ha de hacer es subir el circuito y luego desde un terminal serie, ponerle un valor, recomiendo para empezar el valor 255, y luego el valor 511. Siempre va a contar de forma incremental, es decir, desde 0 al valor que le hayas puesto. Para números mayores de 255 simplemente vuelve a comenzar, así que si ponemos el valor 511 veremos que se repite dos veces, pero con la particularidad de que cuando comienza y cuando termina lo hace de forma progresiva.


Ya lo he probado con un motor de pasos (un Nema 17) y funciona como se espera, pero hay que añadir más cosas para que el tipo de movimiento sea perfecto. Lo que quiero decir es que se necesita una velocidad inicial mínima y de crucero máxima, para que el motor tenga un comportamiento "natural" y eso es lo que me falta por hacer. Espero no tardar mucho en lograrlo, será entonces cuando suba un vídeo de demostración.


Saludos.

Numerical_S-Curve.ice

Democrito

unread,
Jun 7, 2020, 6:52:23 AM6/7/20
to FPGAwars: explorando el lado libre
Anoche se me olvidó comentar que si introducimos el valor 0, dará error. Si introducimos el valor 1 ó 2, no salen esos números de pulsos. Esto se debe a que la salida está dividido entre 2 (y ajustes internos del algoritmo) y es a partir del valor 3 en adelante que dará el mismo número de pulsos que le hayamos introducido. De todas formas, para valores tan tan bajos el "smooth" no tiene sentido. Lo que tengo pensado hacer es que a partir de cierto valor (por ejemplo 10) activar el "smooth" y valores más bajos de ese entonces darle una velocidad constante mínima para completar ese corto recorrido.

Otra cosa que estoy ideando es crear una proporcionalidad con las velocidades, ya que si el valor de entrada (pulsos o distancia deseada) es muy alto, el arrancar y el parar se hace demasiado lento. Ese comportamiento es completamente normal dado este tipo de algoritmo, pero creo que se puede jugar con proporciones (aparte de acotar una velocidad máxima y mínima) para que en distancias largas vaya más rápido en arranque y paradas.

Juan Manuel Yañez

unread,
Jun 7, 2020, 6:55:43 AM6/7/20
to FPGAwars: explorando el lado libre
Hola Demócrito

Acabo de probarlo en el serial terminal con el valor 255, va perfecto: el contador binario en los leds acelera al principio y después decrece.

Un efecto muy chulo y muy bien discurrido

Muchas gracias!

Democrito

unread,
Jun 7, 2020, 7:01:59 AM6/7/20
to FPGAwars: explorando el lado libre
Gracias por probarlo Juan Manuel!

Democrito

unread,
Jun 7, 2020, 8:45:32 AM6/7/20
to FPGAwars: explorando el lado libre
En un anterior post comenté que ya lo había probado con un Nema 17 y se me ha ocurrido mostrar esa parte, pese a que todavía queda mucho por hacer, pero se muestra el tipo de movimiento.

Antes de ver el vídeo comento lo siguiente:

200 pasos es una revolución completa en un Nema 17 sin semipasos, meto ese valor como primera prueba y luego meto 400, 600, 800, 1000 y 2000, siempre múltiplos de 200 para que fuesen números de vueltas distintas pero siempre terminar y acabar en el mismo punto. Por cierto, el sonido también delata los incrementos y decrementos de velocidad.


Adjunto el ICE que he utilizado en el vídeo, pero si quieres probarlo comento por si las moscas lo siguiente:

Los Nema 17 son motores de pasos bipolares (4 cables), el driver más simple para manejarlo es con un puente en H y es como yo lo estoy utilizando de momento. La combinación de 1s y 0s que hace mover el motor es distinta si el motor es unipolar (5 ó 6 cables y suelen manejarse con un ULN2003). Lo ideal sería manejar la etapa de potencia con los drivers que se usan en impresoras 3D que permiten micro-pasos, entonces la cosa sería muy fina.

driver motor icestudio.PNG

Para cambiar las secuencias y adaptarlo a un motor diferente del Nema 17 hay que hacer doble clic en el módulo de control del motor de pasos y poner las secuencias que correspondan a tu motor.

Adjunto ICE.

Saludos.


smooth_Stepper_test.ice

Juan Manuel Yañez

unread,
Jun 7, 2020, 11:35:33 AM6/7/20
to FPGAwars: explorando el lado libre
Por si te apetece verlo en VGA, te adjunto este fichero. Ya lo tenía hecho, simplemente añadí tu bloque como variable "tiempo".

Se visualiza un cuadrado que se mueve a la velocidad descrita por tu algoritmo.
Cambiando los valores en el terminal serie llega más o menos lejos en la pantalla.

Saludos

smooth_VGA.ice

Obijuan

unread,
Jun 7, 2020, 1:49:33 PM6/7/20
to FPGAwars: explorando el lado libre
Buenísimo!!! He probado la versión de la VGA de Juan Manuel, y va muy bien 🙂 Se ve perfectamente cómo acelera y frena

¡Gracias!

Saludos, Obijuan

Democrito

unread,
Jun 7, 2020, 2:28:14 PM6/7/20
to FPGAwars: explorando el lado libre
A ver si me hago o compro el cacharrillo ese de la VGA... Con el tiempo también quiero clavar los dientes ahí.

Me guardo tu ICE Juan Manuel, me gusta mucho todo lo que estás sacando y la creatividad que aplicas!

charli va

unread,
Jun 8, 2020, 7:34:58 AM6/8/20
to fpga-wars-explora...@googlegroups.com
Se mueve genial!! la verdad que mola mucho, esperando ver vuestra evolución!

El dom., 7 jun. 2020 a las 20:28, Democrito (<spo...@gmail.com>) escribió:
A ver si me hago o compro el cacharrillo ese de la VGA... Con el tiempo también quiero clavar los dientes ahí.

Me guardo tu ICE Juan Manuel, me gusta mucho todo lo que estás sacando y la creatividad que aplicas!

--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/fpga-wars-explorando-el-lado-libre/0757cce1-9ad7-41e7-b895-5b46acbc0a8fo%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages