Tabla de contenido:

Rpibot - Acerca del aprendizaje de la robótica: 9 pasos
Rpibot - Acerca del aprendizaje de la robótica: 9 pasos

Video: Rpibot - Acerca del aprendizaje de la robótica: 9 pasos

Video: Rpibot - Acerca del aprendizaje de la robótica: 9 pasos
Video: Обучение РПА - 1 | Учебное пособие по RPA для начинающих | Обучающие видеоролики UiPath | Эдурека 2024, Mes de julio
Anonim
Rpibot - Acerca del aprendizaje de la robótica
Rpibot - Acerca del aprendizaje de la robótica

Soy un ingeniero de software integrado en una empresa automotriz alemana. Comencé este proyecto como una plataforma de aprendizaje para sistemas integrados. El proyecto se canceló temprano pero lo disfruté tanto que continué en mi tiempo libre. Este es el resultado…

Tenía los siguientes requisitos:

  • Hardware simple (el foco es el software)
  • Hardware barato (unos 100 €)
  • Ampliable (algunas opciones ya forman parte de la descripción)
  • Suministro de voltaje para todos los componentes desde una sola fuente de 5V (powerbank)

En realidad, no había un objetivo aparte del aprendizaje. La plataforma se puede utilizar para aprendizaje, vigilancia, concursos de robótica, …

No es un tutorial para principiantes. Necesitas algunos conocimientos básicos sobre:

  • Programación (Python)
  • Electrónica básica (para conectar módulos juntos con el voltaje correcto)
  • Teoría básica de control (PID)

Finalmente, probablemente se enfrente a problemas como yo. Con algo de curiosidad y perseverancia, pasará por el proyecto y resolverá los desafíos. Mi código es lo más simple posible y las líneas de código críticas están comentadas para dar pistas.

El código fuente completo y los archivos están disponibles aquí:

Suministros:

Mecánica

  • 1x tablero de madera contrachapada (tamaño A4, 4 mm de grosor)
  • 3x M4 x 80 Tornillo y tuerca
  • 2x Motorreductores con eje secundario de salida para encoder. Ruedas.
  • 1x rueda libre

1x montaje de cámara de giro e inclinación (opcional)

Electrónica

  • 1x Raspberry Pi Zero con cabezal y cámara
  • 1x servocontrol PCA 9685
  • 2x circuito y rueda codificadora óptica
  • 1x cables de puente hembra
  • 1x banco de energía USB
  • 1x controlador de motor dual DRV8833
  • 2x Micro servos SG90 para giro e inclinación de la cámara (opcional)
  • 1x MPU9250 IMU (opcional)
  • 1x sensor de distancia ultrasónico HC-SR04 (opcional)
  • 1x tablero perforado y alambre de soldadura, cabezales,…

Paso 1: construya el chasis

Construye el chasis
Construye el chasis
Construye el chasis
Construye el chasis
Construye el chasis
Construye el chasis

No soy un buen diseñador mecánico. Además, el objetivo del proyecto es no pasar demasiado tiempo en el chasis. De todos modos definí los siguientes requisitos:

  • Materiales baratos
  • Montaje y desmontaje rápido
  • Ampliable (por ejemplo, espacio para sensores añadidos)
  • Materiales ligeros para ahorrar energía para la electrónica.

Se puede hacer un chasis fácil y económico de madera contrachapada. Es fácil de mecanizar con una sierra de marquetería y un taladro manual. Puede pegar pequeñas piezas de madera para crear los soportes para sensores y motores.

Piense en la sustitución de componentes defectuosos o la depuración eléctrica. Las partes principales deben fijarse con tornillos para que sean reemplazables. Una pistola de pegamento caliente puede ser simple, pero probablemente no sea la mejor manera de construir un chasis … Necesitaba mucho tiempo para pensar en un concepto sencillo para desmontar las piezas fácilmente. La impresión 3D es una buena alternativa, pero puede resultar bastante cara o llevar mucho tiempo.

La rueda libre es finalmente muy ligera y fácil de montar. Las alternativas eran todas pesadas o llenas de fricción (probé un par de ellas antes de encontrar la última). Solo tuve que cortar un espaciador de madera para nivelar la rueda libre de cola después de montar las ruedas principales.

Propiedades de la rueda (para cálculos de software)

Circunferencia: 21, 5 cm Pulsos: 20 pulsos / rev. Resolución: 1, 075 cm (finalmente 1 pulso es de aproximadamente 1 cm, lo cual es fácil para los cálculos de software)

Paso 2: Electrónica y cableado

Electrónica y cableado
Electrónica y cableado
Electrónica y cableado
Electrónica y cableado
Electrónica y cableado
Electrónica y cableado

El proyecto utiliza diferentes módulos como se muestra en el diagrama.

La Raspberry Pi Zero es el controlador principal. Está leyendo los sensores y controlando los motores mediante una señal PWM. Está conectado a un PC remoto por wifi.

El DRV8833 es un puente en H de doble motor. Proporciona la corriente suficiente a los motores (lo que la Raspberry Pi no puede hacer ya que las salidas solo pueden entregar algunos mA).

El codificador óptico proporciona una señal de forma cuadrada cada vez que la luz pasa por las ruedas del codificador. Usaremos las interrupciones HW de la Raspberry Pi para obtener la información cada vez que la señal esté alternando.

El pca9695 es un tablero de servocontrol. Se comunica mediante un bus serie I2C. Esta placa proporciona las señales PWM y el voltaje de suministro que controlan los servos de giro e inclinación de la leva.

El MPU9265 es una aceleración de 3 ejes, una velocidad de rotación angular de 3 ejes y un sensor de flujo magnético de 3 ejes. Lo usaremos principalmente para obtener el rumbo de la brújula.

Los diferentes módulos están todos conectados entre sí mediante un cable de puente. Una placa de pruebas actúa como despachador y proporciona voltajes de suministro (5 V y 3,3 V) y tierra. Todas las conexiones se describen en la tabla de conexiones (ver anexo). Conectar 5V a una entrada de 3.3V probablemente destruirá su chip. Tenga cuidado y verifique todo su cableado dos veces antes de suministrar (aquí, especialmente, se debe considerar el codificador). Debe medir los voltajes de suministro principal en el tablero de despacho con un multímetro antes de conectar todos los tableros. Los módulos se fijaron mediante tornillos de nailon en el chasis. También aquí estaba feliz de tenerlos reparados, pero también extraíbles en caso de mal funcionamiento.

La única soldadura fue finalmente los motores y la placa de pruebas y los cabezales. Para ser honesto, me gustan los cables de puente, pero pueden provocar una conexión suelta. En algunas situaciones, algunas supervisiones de software pueden ayudarlo a analizar las conexiones.

Paso 3: infraestructura de software

Infraestructura de software
Infraestructura de software
Infraestructura de software
Infraestructura de software

Después de lograr la mecánica, configuraremos alguna infraestructura de software para tener cómodas condiciones de desarrollo.

Git

Este es un sistema de control de versiones de código abierto y gratuito. Se usa para administrar proyectos grandes como Linux, pero también se puede usar fácilmente para proyectos pequeños (ver Github y Bitbucket).

Los cambios del proyecto se pueden rastrear localmente y también se pueden enviar a un servidor remoto para compartir software con la comunidad.

Los principales comandos utilizados son:

git clone https://github.com/makerobotics/RPIbot.git [Obtenga el código fuente y la configuración de git]

git pull origin master [obtenga lo último del repositorio remoto]

git status [obtenga el estado del repositorio local. ¿Hay algún archivo cambiado?] Git log [obtener la lista de confirmaciones] git add. [agregar todos los archivos modificados a la etapa para ser considerados para la próxima confirmación] git commit -m "comentario para confirmación" [confirmar los cambios en el repositorio local] git push origin master [enviar todas las confirmaciones al repositorio remoto]

Inicio sesión

Python proporciona algunas funciones de registro integradas. La estructura del software debería definir ya todo el marco de registro antes de comenzar con el desarrollo posterior.

El registrador se puede configurar para registrar con un formato definido en el terminal o en un archivo de registro. En nuestro ejemplo, el registrador está configurado por la clase de servidor web, pero también podríamos hacerlo por nuestra cuenta. Aquí solo configuramos el nivel de registro en DEBUG:

logger = logging.getLogger (_ nombre_)

logger.setLevel (registro. DEBUG)

Medición y trazado

Para analizar señales a lo largo del tiempo, lo mejor es trazarlas en un gráfico. Como la Raspberry Pi solo tiene una terminal de consola, rastrearemos los datos en un archivo csv separado por punto y coma y lo trazaremos desde la PC remota.

El archivo de seguimiento separado por punto y coma es generado por nuestro código Python principal y debe tener encabezados como este:

marca de tiempo; yawCorr; encoderR; I_L; odoDistance; ax; encoderL; I_R; yaw; eSpeedR; eSpeedL; pwmL; speedL; CycleTimeControl; wz; pwmR; speedR; Iyaw; hdg; m_y; m_x; eYnsew; cycleTimeTime

1603466959.65;0;0;25;0.0;-0.02685546875;0;25;0;25;25;52;0.0;23;0.221252441406;16;0.0;0;252.069366413;-5.19555664062;-16.0563964844;0;6; 1603466959.71;0;0;50;0.0;0.29150390625;0;50;0;25;25;55;0.0;57;-8.53729248047;53;0.0;0;253.562118111;-5.04602050781;-17.1031494141;0;6; 1603466959.76;0;-1;75;0.0;-0.188232421875;1;75;2;25;25;57;0;52;-24.1851806641;55;0;0;251.433794171;-5.64416503906;-16.8040771484;2;7;

La primera columna contiene la marca de tiempo. Las siguientes columnas son gratuitas. Se llama al script de trazado con una lista de columnas a trazar:

remoto @ pc: ~ / python rpibot_plotter -f trace.csv -p speedL, speedR, pwmL, pwmR

El script de trazado está disponible en la carpeta de herramientas:

El trazador está usando mathplotlib en Python. Debe copiarlo en su PC.

Para mayor comodidad, el script de Python es llamado por un script de bash (plot.sh) que se usa para copiar el archivo de rastreo de Raspberry Pi a la PC remota y llamar al trazador con una selección de señal. si el archivo debe copiarse. Esto fue más conveniente para mí en lugar de copiar manualmente cada vez. "sshpass" se utiliza para copiar el archivo de la Raspberry Pi a la PC remota a través de scp. Es capaz de copiar un archivo sin pedir la contraseña (se pasa como parámetro).

Finalmente se abre una ventana con el gráfico como se muestra en la imagen.

Comunicación remota

La interfaz de desarrollo de Raspberry Pi es SSH. Los archivos se pueden editar directamente en el destino o copiarlos con scp.

Para controlar el robot, se ejecuta un servidor web en el Pi, que proporciona control a través de Websockets. Esta interfaz se describe en el siguiente paso.

Configurar la Raspberry Pi

Hay un archivo que describe la configuración de la Raspberry Pi en la carpeta "doc" del código fuente (setup_rpi.txt). No hay muchas explicaciones, pero sí muchos comandos y enlaces útiles.

Paso 4: la interfaz de usuario

La interfaz de usuario
La interfaz de usuario

Usamos el servidor web ligero Tornado para alojar la interfaz de usuario. Es un módulo de Python al que llamamos cuando iniciamos el software de control del robot.

Arquitectura de software

La interfaz de usuario se construye con los siguientes archivos: gui.html [Describiendo los controles y el diseño de la página web] gui.js [Contiene el código javascript para manejar los controles y abrir una conexión websocket a nuestro robot] gui.css [Contiene los estilos de los controles html. Las posiciones de los controles se definen aquí]

La comunicación websocket

La interfaz de usuario no es la mejor, pero está haciendo el trabajo. Me centré aquí en tecnologías que eran nuevas para mí, como Websockets.

El sitio web se está comunicando con el servidor web del robot mediante Websockets. Este es un canal de comunicación bidireccional que permanecerá abierto cuando se inicie la conexión. Enviamos los comandos del robot a través de Websocket a la Raspberry Pi y obtenemos información (velocidad, posición, flujo de la cámara) para mostrarla.

El diseño de la interfaz

La interfaz de usuario tiene una entrada manual para los comandos. Esto se usó al principio para enviar comandos al robot. Una casilla de verificación es encender y apagar la transmisión de la cámara. Los dos controles deslizantes controlan la panorámica y la inclinación de la cámara. La parte superior derecha de la interfaz de usuario controla el movimiento del robot. Puede controlar la velocidad y la distancia objetivo. La información básica de telemetría se muestra en el dibujo del robot.

Paso 5: Programación de la plataforma del robot

Programación de la plataforma del robot
Programación de la plataforma del robot
Programación de la plataforma del robot
Programación de la plataforma del robot
Programación de la plataforma del robot
Programación de la plataforma del robot

Esta parte fue el objetivo principal del proyecto. Refactoré gran parte del software cuando introduje el nuevo chasis con los motores de CC. Usé Python como lenguaje de programación por diferentes razones:

  • Es el idioma principal de Raspberry Pi
  • Es un lenguaje de alto nivel con muchas funciones y extensiones integradas.
  • Está orientado a objetos, pero también se puede utilizar para programación secuencial.
  • No se necesita compilación ni cadena de herramientas. Edite el código y ejecútelo.

Arquitectura de software principal

El software está orientado a objetos, dividido en unos pocos objetos. Mi idea era dividir el código en 3 bloques funcionales:

Sentido Pensar Actuar

Sense.py

Adquisición y procesamiento del sensor principal. Los datos se almacenan en un diccionario para ser utilizados en la siguiente etapa.

Control.py

Una subclase de actuación es controlar los motores y servos después de alguna abstracción. El objeto principal de Control es manejar los comandos de alto nivel y también los algoritmos de control (PID) para el motor.

rpibot.py

Este objeto principal es administrar el servidor web Tornado y crear instancias de las clases de detección y control en subprocesos separados.

Cada módulo se puede ejecutar solo o como parte de todo el proyecto. Solo puede detectar e imprimir la información del sensor para verificar que los sensores estén conectados correctamente y entreguen la información correcta.

El control PID

La primera tarea es averiguar qué queremos controlar. Empecé intentando controlar la posición, que era muy compleja y no ayudaba mucho.

Finalmente, queremos controlar la velocidad de cada rueda y también la dirección del robot. Para hacer eso, tenemos que conectar en cascada dos lógicas de control.

Para aumentar la complejidad paso a paso, el robot debe controlarse:

lazo abierto (con potencia constante)

pwm = K

luego agregue el algoritmo de ciclo cerrado

pwm = Kp.speedError + Ki. Integration (speedError)

y finalmente agregue el control de dirección como último paso.

Para el control de velocidad utilicé un control "PI" y "P" solo para la guiñada. Configuré manualmente los parámetros experimentando. Probablemente se podrían utilizar aquí parámetros mucho mejores. Mi objetivo era solo una línea recta y casi lo consigo. Creé una interfaz en el software para escribir algunas variables mediante la interfaz de usuario. Establecer el parámetro Kp en 1.0 necesita el siguiente comando en la interfaz de usuario:

SET; Kp; 1.0

Podría establecer el parámetro P lo suficientemente bajo para evitar cualquier sobrepaso. El error restante se corrige con el parámetro I (error integrado)

Fue difícil para mí descubrir cómo conectar ambos controles en cascada. La solución es simple, pero probé muchas otras formas antes … Así que finalmente, cambié el objetivo de velocidad de las ruedas para girar en una u otra dirección. Cambiar la salida del control de velocidad directamente fue un error ya que el control de velocidad estaba tratando de eliminar esta perturbación.

Se adjunta el diagrama de control utilizado. Muestra solo el lado izquierdo del control del robot.

Paso 6: las calibraciones del sensor

Las calibraciones del sensor
Las calibraciones del sensor
Las calibraciones del sensor
Las calibraciones del sensor
Las calibraciones del sensor
Las calibraciones del sensor

Lo primero a considerar es que toda la IMU debe funcionar correctamente. Pedí 3 piezas y las envié de vuelta hasta que tuve un sensor de trabajo completo. Cada sensor anterior tenía algunas partes del sensor que no funcionaban correctamente o no funcionaban en absoluto. Usé algunos scripts de ejemplo para probar los conceptos básicos antes de montarlo en el robot.

Las señales del sensor IMU deben calibrarse antes de usarlo. Algunas señales de los sensores dependen del ángulo y la posición de montaje.

Las calibraciones de velocidad de aceleración y rotación

La calibración más sencilla es la de la aceleración longitudinal (A_x). En reposo debería haber alrededor de 0 m / s². Si gira el sensor correctamente, puede medir la gravedad (alrededor de 9, 8 m / s²). Para calibrar a_x, basta con montarlo correctamente y luego definir el offset para obtener 0 m / s² en reposo. Ahora A_x está calibrado. Puede obtener las compensaciones para las velocidades de rotación de manera similar en parada.

La calibración del magnetómetro para la brújula

Es necesaria una calibración más compleja para los sensores de campo magnético. Usaremos m_x y m_y para obtener el campo magnético en el nivel horizontal. Tener m_x y m_y nos dará la oportunidad de calcular el rumbo de una brújula.

Para nuestro simple propósito, solo calibraremos la desviación del hierro duro. Esto debe realizarse ya que el sensor está en la posición final, ya que depende de las perturbaciones del campo magnético.

Registramos m_x y m_y mientras giramos el robot alrededor del eje z. Trazamos m_x vs m_y en un gráfico XY. El resultado en una elipsis como se muestra en la imagen. La elipsis debe estar centrada en el origen. Aquí consideramos los valores máximo y mínimo de m_x y m_y para obtener las compensaciones en ambas direcciones. Finalmente comprobamos la calibración y vemos que la elipsis ahora está centrada.

La calibración de hierro dulce significaría que cambiamos la imagen de una elipsis a un círculo. Esto se puede hacer agregando un factor en cada valor de senor.

Ahora se puede codificar una rutina de prueba para volver a calibrar o al menos para verificar que los sensores aún estén calibrados.

El rumbo de la brújula

Los datos del magnetómetro se utilizarán ahora para calcular el rumbo de la brújula. Para ello, tenemos que convertir las señales m_x y m_y en un ángulo. Python proporciona directamente la función math.atan2 que tiene este objetivo. El cálculo completo se define en el archivo mpu9250_i2c.py ("calcHeading (mx, my, mz)").

Paso 7: diseños alternativos

Diseños alternativos
Diseños alternativos
Diseños alternativos
Diseños alternativos
Diseños alternativos
Diseños alternativos

El proyecto tomó mucho tiempo ya que el diseño estaba completamente abierto. Para cada componente hice una implementación de prototipo y experimenté los límites del sistema.

El tema más complejo fue el codificador de rueda. Probé 3 opciones diferentes antes de encontrar el codificador óptico que se usa actualmente. Creo que las soluciones abortadas también son muy interesantes en un proyecto de este tipo. Se trata de las partes en las que más aprendí.

Servo de rotación continua conectado a pca 9695

Para evitar un puente H adicional para un motor de CC, primero comencé con servos de rotación continua. Estos fueron impulsados por el servocontrolador pca 9695 ya presente. Toda la mecánica de propulsión y la electrónica correspondiente eran mucho más simples. Este diseño tenía dos inconvenientes:

  • El pobre rango de control de los servos.
  • La ubicación de retención del codificador faltante

Los servos comienzan a moverse con 50% pwm y alcanzan la máxima velocidad en aproximadamente el 55%. Este es un rango de control muy pobre.

Sin un codificador que sostenga, fue muy difícil encontrar un codificador listo para usar. Probé 3 codificadores de reflectancia diferentes que estaban montados en el chasis. Grabé una rueda codificadora de fabricación propia en la parte exterior de la rueda con secciones en blanco y negro. Usé los sensores QTR-1RC que necesitan mucho procesamiento de señal para obtener la señal correcta. La Raspberry Pi no pudo realizar ese tipo de procesamiento en tiempo real. Así que decidí agregar un NodeMCU D1 mini como controlador en tiempo real al robot. Fue conectado a la Raspberry Pi por el UART serial para entregar los datos procesados del sensor. El NodeMCU también estaba manejando el sensor HC-SR04. La mecánica era difícil y no muy robusta, la línea serial recibía ruido de la línea I2C y los motores, así que finalmente construí la segunda versión del chasis con motores DC de engranajes simples impulsados por un puente en H. Estos motores tienen un eje de salida secundario para colocar un codificador óptico.

Paso 8: procesamiento de imágenes

Procesamiento de imágenes
Procesamiento de imágenes
Procesamiento de imágenes
Procesamiento de imágenes
Procesamiento de imágenes
Procesamiento de imágenes
Procesamiento de imágenes
Procesamiento de imágenes

Para mejorar la conducción autónoma, podemos realizar algún procesamiento de imágenes.

La biblioteca opencv es una referencia para eso. Python puede utilizarlo para implementar rápidamente la detección de obstáculos.

Capturamos una imagen y aplicamos algunas tareas de procesamiento de imágenes:

Las primeras pruebas se realizaron con transformaciones de Canny y Sobel. Canny puede ser un buen candidato, pero no es lo suficientemente sensato. Sobel es demasiado sensible (se han detectado demasiados objetos).

Finalmente hice mi propio filtro para mezclar todos los degradados horizontales y verticales (detectar muebles):

  • Transforma la imagen en color en una imagen de nivel de gris
  • Difumina la imagen para eliminar los pequeños ruidos
  • Umbral de la imagen a una imagen en blanco y negro
  • Ahora detectamos gradientes horizontales y verticales para detectar objetos como paredes y muebles.
  • Filtramos solo los grandes contornos restantes (ver contornos coloreados en la imagen)

Ahora podemos usar esta nueva información para detectar obstáculos …

Paso 9: Pasos siguientes …

Próximos pasos…
Próximos pasos…
Próximos pasos…
Próximos pasos…

Ahora, tenemos una plataforma de robot simple con sensores, actuadores y una cámara. Mi objetivo es moverme de forma autónoma y volver a la estación sin agregar más sensores. Para esto, necesitaré los siguientes pasos:

  • Fusión de sensores de señales de rumbo magnético y de guiñada
  • Procesamiento de imágenes de la cámara (solo CPU baja disponible para eso)
  • Detección de colisiones (distancia ultrasónica y cámara)
  • Construcción de mapas u orientación

Ahora ve y crea tus propios desafíos u objetivos …

Recomendado: