Evitando pendientes

Aveces pensamos que las superficies sobre las que se desplaza un robot móvil, son planas y con obstáculos regulares que se pueden evitar al ser detectados. En aplicaciones reales, esto no siempre es cierto: los terrenos naturales no son planos y los obstáculos pueden tener cualquier forma y tamaño. Por ejemplo, las pendientes pueden representar un alto riesgo. Una pendiente muy pronunciada puede volcar el robot, impidiendo su desplazamiento. ¿Cómo puede un robot medir su inclinación mientras se desplaza? ¡Con un acelerómetro! que es un instrumento para medir la intensidad y la orientación de las aceleraciones y por lo tanto, de la gravedad. Entonces, a partir de la medición de la aceleración, se podría estimar la inclinación del robot con respecto a la gravedad que representa la posición vertical.

Thymio II tiene un acelerómetro y lo puede usar para medir la inclinación del terreno. Un buen ejemplo de una superficie con pendientes variables es una bañera. Por eso, adoptamos una bañera como entorno de prueba:

baignoire-photo-700.jpg

La superficie en el centro de la bañera es aproximadamente plana pero comienza a inclinarse hacia los extremos, y mientras el robot avanza mide su inclinación para evitar pendientes muy pronunciadas. La evasión de pendientes se implementa con el siguiente código:

onevent acc            #cada vez que se actualiza el valor del acelerómetro
   motor.left.target=130-(acc[0]-2)*35-acc[1]*40 
   motor.right.target=130+(acc[0]-2)*35-acc[1]*40

En este código, el robot avanza a una velocidad de 130 si no detecta inclinaciones laterales o adelante/atras; es decir, si los valores acc[0] y acc[1] son muy bajos. Si el robot se inclina lateralmente, es decir, si el valor absoluto de acc[0] aumenta, entonces se hace girar, aumentando la velocidad de una rueda y disminuyéndola en otra. Además, si el robot se inclina hacia adelante o hacia atrás, es decir, si el valor absoluto de acc[1] aumenta, entonces se disminuye o se aumenta la velocidad de ambas ruedas.

Con este comportamiento se obtiene lo siguiente:

En el primer ejemplo el movimiento es irregular debido al ruido en el acelerómetro. Para conseguir un movimiento más suave puedes suavizar los datos del acelerómetro. Una solución es tomar la media de las últimas cuatro mediciones, así por ejemplo:

var accBuffer0[4] = 0,0,0,0    # se guardan los últimos 4 valores de acc[0]
var accBufferPos0 = 0        # se guarda la posición del valor mas antiguo.
var accBuffer1[4] = 0,0,0,0
var accBufferPos1 = 0
var sumacc0
var sumacc1

onevent acc
  accBuffer0[accBufferPos0] = acc[0]-2    #leemos el valor acelerómetro. Restamos 2 Debido a que el acelerómetro no es plano.
  accBufferPos0 = (accBufferPos0 + 1) % 4  #actualizamos el último valor
  sumacc0 = accBuffer0[0] + accBuffer0[1] + accBuffer0[2] + accBuffer0[3] # la sumatoria
  accBuffer1[accBufferPos1] = acc[1]
  accBufferPos1 = (accBufferPos1 + 1) % 4
  sumacc1 = accBuffer1[0] + accBuffer1[1] + accBuffer1[2] + accBuffer1[3]

   motor.left.target=130-sumacc0*15-sumacc1*15
  motor.right.target=130+sumacc0*15-sumacc1*15
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License