Caută cod

Curs Lecția 9 din 10: Evitarea obstacolelor folosind mașina inteligentă 4WD Raspberry Pi Pico

Această lecție face parte din: Mașină inteligentă Raspberry Pi Pico 4WD

Curs Lecția 9 din 10: Evitarea obstacolelor folosind mașina inteligentă 4WD Raspberry Pi Pico

Introducere

Acest ghid, bazat pe Lecția 9 din 10 a cursului Robojax, demonstrează cum să construiești un robot care evită obstacole folosind kit-ul SunFounder Raspberry Pi Pico 4WD Smart Car. Proiectul combină un senzor ultrasonic acționat de un servomotor cu controlul motoarelor pentru a crea un robot care poate naviga autonom în mediul său. Prin rotirea senzorului ca un radar, mașina detectează obstacolele și alege inteligent o cale liberă pentru a înainta, fiind o introducere perfectă în robotică, integrarea senzorilor și navigarea autonomă.

Configurația Sunfounder_Pico4DW-09-Obstacle-avoidance cu un obstacol pe podea

Acest proiect nu este doar o jucărie; este o fundație pentru multe aplicații practice. Iată câteva idei care să te inspire:

  • Robot autonom de explorare: Construiește un robot care poate cartografia și explora o cameră sau o zonă exterioară fără intervenție umană.
  • Aspirator inteligent: Folosește aceleași principii pentru a crea un robot care navighează într-o cameră, evitând mobila și pereții în timp ce curăță.
  • Robot de patrulare pentru securitate: Programează mașina să patruleze un perimetru și folosește senzorul ultrasonic pentru a detecta și raporta obstacole sau intruziuni neașteptate.
  • Platformă educațională pentru IA: Folosește acest proiect ca o rampă de lansare pentru a învăța algoritmi mai complecși, precum găsirea căilor și localizarea și cartografierea simultană (SLAM).

Această lecție se concentrează pe logica de bază și codul care permit mașinii să ia decizii. Mașina folosește un servomotor pentru a roti un senzor ultrasonic, acționând ca un radar pentru a măsura distanțe de la 0 la 180 de grade. Codul analizează aceste date pentru a găsi cea mai largă cale liberă și direcționează mașina să meargă înainte, la stânga sau la dreapta, în consecință. Videoclipul demonstrează întregul proces, de la testarea componentelor individuale până la rularea algoritmului final de evitare a obstacolelor într-un labirint real.

Hardware/Componente

Acest proiect se bazează pe kit-ul SunFounder Raspberry Pi Pico 4WD Smart Car. Componentele esențiale folosite în această lecție sunt:

  • Placa de microcontroler Raspberry Pi Pico
  • Șasiul SunFounder 4WD Smart Car cu patru motoare
  • Placa de driver pentru motoare
  • Senzorul ultrasonic de distanță (tip HC-SR04)
  • Servomotor (pentru rotirea senzorului ultrasonic)
  • Sursa de alimentare (baterii pentru mașină)

Ghid de cablare

Kit-ul SunFounder este conceput pentru o asamblare ușoară, iar cablarea este de obicei pre-conectată printr-o placă de extensie dedicată. Senzorul ultrasonic este montat pe servomotor, care este apoi conectat la placa principală de control. Această configurație permite rotirea senzorului pentru a scana mediul. Pentru o diagramă detaliată de cablare specifică kit-ului tău, consultă documentația oficială SunFounder.

Conexiunile principale implică pinii de trigger și echo ai senzorului ultrasonic și pinul de semnal al servomotorului, toate fiind conectate la pini GPIO specifici de pe Raspberry Pi Pico. Driverul de motoare este, de asemenea, conectat la Pico pentru a controla cele patru motoare de acționare. Videoclipul menționează că documentația completă, inclusiv diagramele de cablare, este disponibilă pentru descărcare împreună cu kit-ul.

Sunfounder_Pico4DW-09-Obstacle-avoidance_când senzorul ultrasonic detectează un obstacol

Explicația codului

Această lecție se concentrează pe logica din exemplul `obstacle_avoid`. Codul este scris în MicroPython. Deși programul complet este disponibil pentru descărcare, ne vom concentra pe parametrii cheie, configurabili de utilizator, care controlează comportamentul mașinii. Aceștia se găsesc de obicei la începutul scriptului.

Iată principalele variabile pe care le poți ajusta pentru a regla fin performanța robotului tău:


# Parametri radar și de mișcare
radar_reference = 20  # Distanța minimă în cm considerată sigură
step_angle = 10       # Incrementul unghiular pentru fiecare pas al scanării radar
forward_speed = 30    # Viteza motorului pentru deplasarea înainte (0-100)
turn_speed = 50       # Viteza motorului pentru virare (0-100)
forward_scan_angle = 50  # Unghiul pe care servomotorul îl scanează când nu este detectat niciun obstacol
  • radar_reference: Aceasta este distanța critică de siguranță în centimetri. Dacă un obstacol este detectat mai aproape decât această valoare, mașina îl va considera un „pericol” și va iniția o manevră de evitare. În videoclip, aceasta este setată la 20 cm.
  • step_angle: Aceasta definește rezoluția scanării radar. O valoare mai mică (de exemplu, 10 grade) înseamnă o scanare mai detaliată, dar durează mai mult. O valoare mai mare ar fi mai rapidă, dar ar putea rata obstacole înguste.
  • forward_speed & turn_speed: Acestea controlează puterea trimisă către motoare. Le poți ajusta pentru a schimba viteza generală și agilitatea mașinii. Viteza de virare este adesea setată mai mare pentru a asigura că mașina se poate roti eficient.
  • forward_scan_angle: Când nu există un pericol imediat în față, mașina își restrânge scanarea la acest unghi (centrat pe direcția înainte) pentru a verifica obstacolele mai frecvent în calea sa directă, permițând o mișcare înainte mai lină.

Videoclipul explică, de asemenea, logica principală de luare a deciziilor. O funcție `get_direction()` analizează lista citirilor de distanță (convertite în 1 și 0 pentru sigur/nesigur) pentru a găsi cel mai larg traseu continuu de "1". Pe baza locului unde se află acest traseu cel mai larg, funcția returnează o direcție: "înainte", "stânga" sau "dreapta". Bucla principală execută apoi acțiunea corespunzătoare, rotind mașina și rescanând până când traseul din față este liber.

Proiect/Demonstrație Live

Videoclipul oferă o demonstrație amănunțită a proiectului. Începe prin testarea senzorului ultrasonic singur pentru a arăta cum măsoară distanța și tipărește valorile în shell. Instructorul explică apoi algoritmul de evitare a obstacolelor folosind o diagramă de flux, detaliind procesul de luare a deciziilor pentru virarea la stânga și la dreapta. În final, mașina este plasată într-un mic labirint creat din cutii pentru a demonstra comportamentul complet de evitare a obstacolelor în acțiune. Mașina navighează cu succes prin labirint, virând la stânga și la dreapta pentru a găsi un traseu liber în față.

Capitolele Videoclipului

  • [00:00] Introducere în evitarea obstacolelor
  • [01:31] Prezentare generală a kitului SunFounder Smart Car și a caracteristicilor
  • [02:47] Cum funcționează funcția de evitare a obstacolelor
  • [03:34] Testarea senzorului ultrasonic
  • [07:45] Explicarea algoritmului și a diagramei de flux pentru evitarea obstacolelor
  • [12:49] Analiza codului principal de evitare a obstacolelor
  • [15:43] Demonstrație live a logicii de evitare a obstacolelor
  • [22:53] Demonstrație finală cu un labirint de obstacole
  • [24:35] Concluzie și pașii următori

Imagini

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
Limba: 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()

Lucruri de care ai putea avea nevoie

Resurse și referințe

Încă nu sunt resurse.

Fișiere📁

Cod Raspberry Pi