Ir al contenido principal

FollowLine: controlador con dos PID

Con el fin de mejorar la entrada y salida de curva, los principales problemas que tení­a hasta el momento, he decidido incorporar un segundo PID. De este modo, tendrá un controlador para el estado de curva y otro para el estado de recta, con sus correspondientes constantes ajustadas. El gran desafío es como definir correctamente que es curva y que recta. Bien, tras darle algunas vueltas, creo que la opción más sencilla es comprobar si tres puntos tomados a distintas alturas de la lí­nea están alineados o no. En caso de que no lo estén, asumiré que el robot se encuentra en una curva o cualquier otro estado que no sea un recta. La forma de calcular si los puntos están alineados es sencilla. Teniendo tres puntos A, B y C estos pertenecen a la misma línea si: distancia(A,B) + distancia(B,C) = distancia(A,C). Además, hay que añadir una pequeña tolerancia para que funcione correctamente.

Tras ajustar las constantes de cada controlador manualmente, mediante prueba y error, el robot se comporta muy bien en las dos situaciones, permitiendome subir la velocidad. Sin embargo las entradas y salidas de curva siguen siendo deficientes. Revisando el código, me he dado cuenta de que dentro de cada controlador tenía dos variables que conservaban su valor entre frames. Esto es correcto, el problema es que cuando el robot encuentra una nueva curva, por ejemplo, el valor de dichas variables no es el de por defecto (0), si no que tienen un valor que proviene de la curva anterior. Por suerte tiene fácil solución, con resetear las variables del controlador que no está en uso en cada iteración es suficiente.

Una vez arreglado ese detalle, el comportamiento mejora, pero todaví­a es muy brusco en algunas partes. Para suavizarlo he decidido incorporar un buffer de diez unidades donde almaceno el estado del robot (curva o recta) en cada iteración. De este modo puedo establecer la regla de que pase a usarse el controlador de recta sólo si anteriormente se han detectado al menos diez rectas. En cuanto en el buffer entre una curva el controlador seleccionado sería el de curva. 

Aunque parece algo sencillo, he notado una gran mejoría en el comportamiento al incorporarlo. Ahora mismo las entradas y salidas de curva son mucho más suaves. Por otra parte, al incluir dos controladores he suprimido las reglas de control que había introducido antes, ya que realmente no estaban aportando mucho. Tras las mejoras el código es mucho más limpio y claro, a la vez que el rendimiento del robot ha mejorado. He podido completar una vuelta en 1min40s aunque he rebajado un poco la velocidad para ganar más seguridad. Con la estrategia que he venido siguiendo creo que estoy cerca del límite y no creo que pueda conseguir mejorar mucho más mi tiempo. Posiblemente mediante otro camino se pueda, pero no se me ocurre como.




Comentarios

Entradas populares de este blog

Reconstruccion3D: emparejamiento de puntos y cálculo del punto 3D

Como se comentaba en la entrada anterior, una vez tenemos la línea epipolar calculada podemos buscar el punto homólogo correspondiente. Para ello es necesario establecer una métrica para comparar ambos puntos. Tomar simplemente los valores RGB de los puntos no parece la forma más fiable, puesto que puede ser que haya más de un punto similar. Lo ideal sería tomar una región o parche centrada en los puntos. De esta forma la comparación será mucho más fiable y discriminante a lo largo de la epipolar. Es necesario establecer una métrica para comparar ambos parches. Una de las más sencillas es el MSE (Mean Square Error), que promedia el resultado de restar los valores en escala de grises de cada uno de los elementos del parche. Existen otras métricas como comparar histogramas o la correlación, pero considero que es mejor comenzar con la más simple. Como se trata de una diferencia, hay que calcular el MSE entre todas las posibles combinaciones a lo largo de la epipolar. El punto...

Reconstrucción3D: resultados

Tras describir cual ha sido el procedimiento que he seguido durante la práctica, es hora de analizar los resultos. Para visualizar mejor los puntos he decidido utilizar un visor de puntos 3D externo, Meshlab. He notado que a medida que se van pintando los puntos obtenidos en el visor que se adjunta con Gazebo el tiempo de ejecución aumento. Por ello he optado por ir almacenando los puntos en una lista para finalmente guardarlos en un fichero .obj. De esta manera, una vez finalizada la ejecución, es posible cargar el archivo en el visualizador y y observar el resultado de la reconstrucción. Debido a un fallo de programación la reconstrucción salía con los contornos bien dibujados pero en un plano 2D dentro del mundo. Después de arreglar ese pequeño error en una condición, he podido representar los bordes de las figuras en tres dimensiones. Sin embargo, el resultado obtenido tampoco era del todo bueno. Era posible intuir alguna de las figuras pero realmente no estaba bien. Revisando el...

FollowLine: diseño con un PID

En esta siguiente aproximación me he centrado en introducir el controlador PID en el sistema. Tras estudiar su funcionamiento teórico me he decantado por crear una nueva clase que contenga las tres constantes fijas: Kp, Kd y Ki, además de un método que compute la fórmula y devuelva el resultado. Las constantes anteriormente mencionadas no tienen ningún tipo de valor por defecto, dependen mucho del problema a tener en cuenta. Por ello, he obtenido sus valores óptimos mediante prueba y error. Realmente es un trabajo costoso y que toma tiempo, pero si se hece bien el resultado puede ser muy bueno. Para este caso en concreto, he comprobado que apenas se producen cambios en el comportamiento del robot cuando omito la constante Ki, por lo que la fijaré a 0. No entiendo bien porque parece funcionar mejor sin ella, pero realmente lo hace. También he observado que cuando Kd es mucho más grande que Kp el robot sigue las rectas increiblemente, sin oscilar, pero es poco estable en curvas. Sin e...