Nota

Hola, bienvenido a la comunidad de entusiastas de SunFounder Raspberry Pi & Arduino & ESP32 en Facebook. ¡Explora más a fondo Raspberry Pi, Arduino y ESP32 con otros entusiastas!

¿Por qué unirse?

  • Soporte experto: Resuelve problemas postventa y desafíos técnicos con la ayuda de nuestra comunidad y equipo.

  • Aprende y comparte: Intercambia consejos y tutoriales para mejorar tus habilidades.

  • Avances exclusivos: Obtén acceso anticipado a anuncios de nuevos productos y vistas previas.

  • Descuentos especiales: Disfruta de descuentos exclusivos en nuestros productos más recientes.

  • Promociones festivas y sorteos: Participa en sorteos y promociones de temporada.

👉 ¿Listo para explorar y crear con nosotros? Haz clic en [aquí] y únete hoy mismo.

Lucha de Toros

¡Convierte a PiCrawler en un toro enojado! Usa su cámara para seguir y embestir la tela roja.

Ejecutar el Código

cd ~/picrawler/examples
sudo python3 7_bull_fight.py

Ver la Imagen

Después de ejecutar el código, el terminal mostrará el siguiente mensaje:

No desktop !
* Serving Flask app "vilib.vilib" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:9000/ (Press CTRL+C to quit)

Luego puedes ingresar http://<tu IP>:9000/mjpg en el navegador para ver la pantalla de video. Por ejemplo: https://192.168.18.113:9000/mjpg

../_images/display.png

Código

Nota

Puedes Modificar/Restablecer/Copiar/Ejecutar/Detener el código a continuación. Pero antes de eso, necesitas ir a la ruta del código fuente como picrawler\examples. Después de modificar el código, puedes ejecutarlo directamente para ver el efecto.

from picrawler import Picrawler
from time import sleep, time
from robot_hat import Music
from vilib import Vilib

# Create robot and audio controller objects
crawler = Picrawler()
music = Music()

def main():
    # Start camera and enable preview window
    Vilib.camera_start(vflip=False, hflip=False)
    Vilib.display(local=False, web=True)

    # Enable red color detection
    Vilib.color_detect("red")

    speed = 80                  # Movement speed
    last_seen = False           # Indicates whether the red target was detected in previous loop
    last_beep = 0               # Timestamp of last sound playback
    BEEP_COOLDOWN = 1.0         # Minimum interval between sound effects (seconds)

    # Stand once before starting tracking
    crawler.do_step('stand', 40)
    sleep(1.0)

    try:
        while True:
            # Read detection result
            if Vilib.detect_obj_parameter.get('color_n', 0) != 0:

                # Get horizontal coordinate of detected red object
                coordinate_x = Vilib.detect_obj_parameter.get('color_x', 0)

                # Play sound effect with cooldown to avoid spamming
                now = time()
                if now - last_beep >= BEEP_COOLDOWN:
                    try:
                        music.sound_play_threading('./sounds/talk1.wav')
                    except Exception:
                        pass
                    last_beep = now

                # Steering logic based on horizontal position
                # Left side of image
                if coordinate_x < 100:
                    crawler.do_action('turn left', 1, speed)

                # Right side of image
                elif coordinate_x > 220:
                    crawler.do_action('turn right', 1, speed)

                # Center area → move forward
                else:
                    crawler.do_action('forward', 2, speed)

                last_seen = True
                sleep(0.05)

            else:
                # No red target detected

                # Stop movement only once when target is lost
                # This prevents repeated stand() calls that cause "push-up" effect
                if last_seen:
                    crawler.do_step('stand', 40)
                    last_seen = False

                sleep(0.15)

    except KeyboardInterrupt:
        # Stop program safely when Ctrl+C is pressed
        print("\nStop.")

    finally:
        # Cleanup section to avoid exit errors

        # Disable color detection
        try:
            Vilib.color_detect("close")
        except Exception:
            pass

        # Close camera safely
        try:
            Vilib.camera_close()
        except Exception:
            pass

        # Make the robot sit before exit
        try:
            crawler.do_step('sit', 40)
            sleep(1.0)
        except Exception:
            pass

if __name__ == "__main__":
    main()

¿Cómo funciona?

  1. Inicialización de la Cámara

    Vilib.camera_start(vflip=False, hflip=False)
    Vilib.display(local=False, web=True)
    Vilib.color_detect("red")
    

    La cámara se inicia y se habilita la vista previa en la web. Se activa la detección del color rojo. Vilib procesa continuamente los fotogramas en segundo plano y almacena los resultados de detección en detect_obj_parameter.

  2. Preparación del Robot

    crawler.do_step('stand', 40)
    sleep(1.0)
    

    El robot realiza una acción de ponerse de pie antes de comenzar el seguimiento. Un breve retraso garantiza que la postura sea estable.

  3. Detección del Objetivo

    if Vilib.detect_obj_parameter.get('color_n', 0) != 0:
        coordinate_x = Vilib.detect_obj_parameter.get('color_x', 0)
    

    El programa comprueba si se detecta un objeto rojo. Si se detecta, lee la coordenada horizontal central (posición x) del objeto rojo en la imagen.

  4. Lógica de Decisión de Dirección

    if coordinate_x < 100:
        crawler.do_action('turn left', 1, speed)
    elif coordinate_x > 220:
        crawler.do_action('turn right', 1, speed)
    else:
        crawler.do_action('forward', 2, speed)
    

    La imagen se divide en tres zonas horizontales: izquierda, centro y derecha.

    • Zona izquierda → girar a la izquierda

    • Zona derecha → girar a la derecha

    • Zona central → avanzar

    Esto permite que el robot siga y persiga el objeto rojo.

  5. Mecanismo de Enfriamiento del Sonido

    now = time()
    if now - last_beep >= BEEP_COOLDOWN:
        music.sound_play_threading('./sounds/talk1.wav')
        last_beep = now
    

    Un temporizador de enfriamiento evita la reproducción repetida del sonido. El efecto de sonido se reproduce como máximo una vez por segundo, incluso si el objeto sigue siendo detectado.

  6. Manejo de Pérdida del Objetivo

    if last_seen:
        crawler.do_step('stand', 40)
        last_seen = False
    

    Cuando el objeto rojo desaparece, el robot se detiene y vuelve a una posición estable de pie.

    La bandera last_seen garantiza que stand() se llame solo una vez. Esto evita reinicios repetidos de postura que pueden causar vibraciones.

  7. Salida Segura y Limpieza

    finally:
        Vilib.color_detect("close")
        Vilib.camera_close()
        crawler.do_step('sit', 40)
    

    Cuando el programa termina (por ejemplo, al presionar Ctrl+C), se desactiva la detección de color, la cámara se cierra de forma segura, y el robot ejecuta la acción de sentarse.

    Esto evita errores de cámara y comportamientos inestables durante el apagado.