Código de Pesquisa

Aula Lição 9 de 10: Desvio de Obstáculos usando o Carrinho Inteligente 4WD Raspberry Pi Pico

Esta lição faz parte de: Carro inteligente Raspberry Pi Pico 4WD

Aula Lição 9 de 10: Desvio de Obstáculos usando o Carrinho Inteligente 4WD Raspberry Pi Pico

Introdução

Este guia, baseado na Lição 9 do Curso de 10 da Robojax, demonstra como construir um robô desviador de obstáculos usando o kit SunFounder Raspberry Pi Pico 4WD Smart Car. O projeto combina um sensor ultrassônico acionado por servo com controle de motor para criar um robô que pode navegar em seu ambiente de forma autônoma. Ao varrer o sensor como um radar, o carro detecta obstáculos e escolhe inteligentemente um caminho livre para prosseguir, tornando-o uma introdução perfeita à robótica, integração de sensores e navegação autônoma.

Configuração do Sunfounder_Pico4DW-09-Obstacle-avoidance com obstáculo no chão

Este projeto não é apenas um brinquedo; é uma base para muitas aplicações práticas. Aqui estão algumas ideias para inspirar você:

  • Robô de Exploração Autônoma: Construa um robô que possa mapear e explorar uma sala ou área externa sem intervenção humana.
  • Aspirador Inteligente: Use os mesmos princípios para criar um robô que navegue em uma sala, evitando móveis e paredes enquanto limpa.
  • Robô de Patrulha de Segurança: Programe o carro para patrulhar um perímetro e use o sensor ultrassônico para detectar e relatar obstáculos ou intrusões inesperadas.
  • Plataforma Educacional para IA: Use este projeto como um trampolim para aprender sobre algoritmos mais complexos, como busca de caminhos e localização e mapeamento simultâneos (SLAM).

Esta lição foca na lógica central e no código que permitem ao carro tomar decisões. O carro usa um motor servo para girar um sensor ultrassônico, atuando como um radar para medir distâncias de 0 a 180 graus. O código analisa esses dados para encontrar o caminho livre mais amplo e direciona o carro para mover-se para frente, esquerda ou direita conforme necessário. O vídeo demonstra todo o processo, desde o teste dos componentes individuais até a execução do algoritmo final de desvio de obstáculos em um labirinto do mundo real.

Hardware/Componentes

Este projeto é baseado no kit SunFounder Raspberry Pi Pico 4WD Smart Car. Os componentes essenciais usados nesta lição são:

  • Placa microcontroladora Raspberry Pi Pico
  • Chassi SunFounder 4WD Smart Car com quatro motores
  • Placa de driver de motor
  • Sensor ultrassônico de distância (tipo HC-SR04)
  • Motor servo (para girar o sensor ultrassônico)
  • Fonte de alimentação (baterias para o carro)

Guia de Conexões

O kit SunFounder é projetado para fácil montagem, e as conexões geralmente são pré-conectadas por meio de uma placa de expansão dedicada. O sensor ultrassônico é montado no motor servo, que é então conectado à placa de controle principal. Essa configuração permite que o sensor seja girado para escanear o ambiente. Para um diagrama de conexões detalhado específico do seu kit, consulte a documentação oficial da SunFounder.

As conexões principais envolvem os pinos de trigger e echo do sensor ultrassônico, e o pino de sinal do motor servo, todos conectados a pinos GPIO específicos no Raspberry Pi Pico. O driver do motor também é conectado ao Pico para controlar os quatro motores de tração. O vídeo menciona que a documentação completa, incluindo diagramas de conexões, está disponível para download com o kit.

Sunfounder_Pico4DW-09-Obstacle-avoidance_quando o ultrassônico detecta obstáculo

Explicação do Código

Esta lição foca na lógica dentro do exemplo `obstacle_avoid`. O código é escrito em MicroPython. Embora o programa completo esteja disponível para download, vamos nos concentrar nos principais parâmetros configuráveis pelo usuário que controlam o comportamento do carro. Eles geralmente são encontrados no topo do script.

Aqui estão as principais variáveis que você pode ajustar para ajustar o desempenho do seu robô:


# Parâmetros de radar e movimento
radar_reference = 20  # Distância mínima em cm para ser considerada segura
step_angle = 10       # O incremento de ângulo para cada etapa de varredura do radar
forward_speed = 30    # Velocidade do motor para mover para frente (0-100)
turn_speed = 50       # Velocidade do motor para girar (0-100)
forward_scan_angle = 50  # O ângulo que o servo varre quando nenhum obstáculo é detectado
  • radar_reference: Esta é a distância de segurança crucial em centímetros. Se um obstáculo for detectado mais próximo que esse valor, o carro o considerará um "perigo" e iniciará uma manobra de desvio. No vídeo, isso é definido como 20 cm.
  • step_angle: Isso define a resolução da varredura do radar. Um valor menor (por exemplo, 10 graus) significa uma varredura mais detalhada, mas leva mais tempo. Um valor maior seria mais rápido, mas poderia perder obstáculos estreitos.
  • forward_speed & turn_speed: Esses controlam a potência enviada aos motores. Você pode ajustá-los para mudar a velocidade geral e a agilidade do carro. A velocidade de giro geralmente é definida mais alta para garantir que o carro possa girar efetivamente.
  • forward_scan_angle: Quando não há perigo imediato à frente, o carro estreita sua varredura para este ângulo (centrado na frente) para verificar obstáculos com mais frequência em seu caminho direto, permitindo um movimento para frente mais suave.

O vídeo também explica a principal lógica de tomada de decisão. Uma função `get_direction()` analisa a lista de leituras de distância (convertidas em 1s e 0s para seguro/inseguro) para encontrar o caminho contínuo mais largo de "1s". Com base em onde esse caminho mais largo está, a função retorna uma direção: "frente", "esquerda" ou "direita". O loop principal então executa a ação correspondente, girando o carro e reescaneando até que o caminho à frente esteja livre.

Projeto/Demonstração ao Vivo

O vídeo fornece uma demonstração completa do projeto. Ele começa testando o sensor ultrassônico sozinho para mostrar como ele mede a distância e imprime os valores no shell. O instrutor então explica o algoritmo de desvio de obstáculos usando um fluxograma, detalhando o processo de tomada de decisão para virar à esquerda e à direita. Finalmente, o carro é colocado em um pequeno labirinto criado com caixas para demonstrar o comportamento completo de desvio de obstáculos em ação. O carro navega com sucesso pelo labirinto, virando à esquerda e à direita para encontrar um caminho livre à frente.

Capítulos do Vídeo

  • [00:00] Introdução ao Desvio de Obstáculos
  • [01:31] Visão Geral do Kit de Carro Inteligente SunFounder e Recursos
  • [02:47] Como Funciona o Recurso de Desvio de Obstáculos
  • [03:34] Testando o Sensor Ultrassônico
  • [07:45] Explicando o Algoritmo de Desvio de Obstáculos e o Fluxograma
  • [12:49] Analisando o Código Principal de Desvio de Obstáculos
  • [15:43] Demonstração ao Vivo da Lógica de Desvio de Obstáculos
  • [22:53] Demonstração Final com um Labirinto de Obstáculos
  • [24:35] Conclusão e Próximos Passos

Imagens

pico-4wd_main
pico-4wd_main
PICOBOARDWHITEANGLE2_1200x857
PICOBOARDWHITEANGLE2_1200x857
Sunfounder_Pico4DW-09-Obstacle-avoidance setup with obstacle on the floor
Sunfounder_Pico4DW-09-Obstacle-avoidance setup with obstacle on the floor
Sunfounder_Pico4DW-09-Obstacle-avoidance_when ultrasonic detects obstacle
Sunfounder_Pico4DW-09-Obstacle-avoidance_when ultrasonic detects obstacle
909-Lesson 9/10 Pi Pico 4WD card Python code: obstacle avoid
Idioma: C++
# Lesson 9/10 Pi Car Pico 4WD: Obstacle avoid
# Download and resource page https://robojax.com/RJT631
import pico_4wd as car
import time

car.RADAR_REFERENCE = 20
car.RADAR_STEP_ANGLE = 10
MOTOR_FORWARD_POWER = 30
MOTOR_TURNING_POWER = 50

FORWARD_SCAN_ANGLE = 50

car.set_radar_scan_angle(FORWARD_SCAN_ANGLE)
status = "Danger"

def get_dir(radar_data):
    # get scan status of 0, 1
    # print(radar_data)
    radar_data = [str(i) for i in radar_data]
    radar_data = "".join(radar_data)
    # Split 0, leaves the free path
    paths = radar_data.split("0")
    # print(paths)
    # print("paths: %s" % paths)
    length_list = []
    # Calculate where is the widest
    for path in paths:
        length_list.append(len(path))
    if max(length_list) < 4:
        return "left"
    # Calculate the direction of the widest 
    i = length_list.index(max(length_list))
    pos = radar_data.index(paths[i])
    pos += (len(paths[i]) - 1) / 2
    delta = len(radar_data) / 3
    
    if pos < delta:
        return "left"
    elif pos > 2 * delta:
        return "right"
    else:
        return "forward"

def main():
    global status
    # General
    while True:
        radar_data = car.radar_scan()
        # print("radar_data: %s" % radar_data)
        # If radar data return a int, means scan not finished, and the int is current angle status
        if isinstance(radar_data, int):
            if radar_data == 0 and status != "Danger":
                print("Danger!")
                status = "Danger"
                car.move("stop")
                car.set_radar_scan_angle(180)
            continue
        else:
            status = "Save"
        
        direction = get_dir(radar_data)

        if direction == "left":
            print("turn left")
            distance = car.get_radar_distance_at(-FORWARD_SCAN_ANGLE/2)
            time.sleep(0.5)
            car.move("left", MOTOR_TURNING_POWER)
            while True:
                distance = car.get_radar_distance_at(-FORWARD_SCAN_ANGLE/2)
                status = car.get_radar_status(distance)
                if status == 1:
                    break
            car.move("stop")
            car.set_radar_scan_angle(FORWARD_SCAN_ANGLE)
        elif direction == "right":
            print("turn right")
            distance = car.get_radar_distance_at(FORWARD_SCAN_ANGLE/2)
            time.sleep(0.5)
            car.move("right", MOTOR_TURNING_POWER)
            while True:
                distance = car.get_radar_distance_at(FORWARD_SCAN_ANGLE/2)
                status = car.get_radar_status(distance)
                if status == 1:
                    break
            car.move("stop")
            car.set_radar_scan_angle(FORWARD_SCAN_ANGLE)
        else:
            print("forward")
            car.set_radar_scan_angle(FORWARD_SCAN_ANGLE)
            car.move("forward", MOTOR_FORWARD_POWER)

try:
    main()
finally:
    car.move("stop")
    car.set_light_off()

Recursos e referências

Ainda não há recursos.

Arquivos📁

Código Raspberry Pi