.. note:: Ciao, benvenuto nella SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Community su Facebook! Approfondisci Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati. **Perché unirsi?** - **Supporto Esperti**: Risolvi problemi post-vendita e sfide tecniche con l'aiuto della nostra community e del nostro team. - **Impara & Condividi**: Scambia suggerimenti e tutorial per migliorare le tue competenze. - **Anteprime Esclusive**: Ottieni accesso anticipato a nuovi annunci di prodotti e anteprime. - **Sconti Speciali**: Approfitta di sconti esclusivi sui nostri prodotti più recenti. - **Promozioni Festive e Giveaway**: Partecipa a promozioni festive e concorsi. 👉 Pronto per esplorare e creare con noi? Clicca [|link_sf_facebook|] e unisciti oggi stesso! .. _py_line_tracking: 5. Tracciamento della Linea ==================================== In questo progetto, useremo il modulo Grayscale per far muovere il PiCar-X lungo una linea. Utilizza del nastro adesivo scuro per tracciare una linea il più possibile diritta, senza troppe curve. Potrebbe essere necessario fare alcuni esperimenti se il PiCar-X si discosta dalla linea. **Esegui il Codice** .. raw:: html .. code-block:: cd ~/picar-x/example sudo python3 5.minecart_plus.py Dopo aver eseguito il codice, il PiCar-X si muoverà lungo la linea. **Codice** .. note:: Puoi **Modificare/Resettare/Copiare/Eseguire/Interrompere** il codice qui sotto. Prima di farlo, devi andare nel percorso del codice sorgente come ``picar-x/example``. Dopo aver modificato il codice, puoi eseguirlo direttamente per vedere l'effetto. .. raw:: html .. code-block:: python from picarx import Picarx from time import sleep px = Picarx() # px = Picarx(grayscale_pins=['A0', 'A1', 'A2']) # Esegui ./calibration/grayscale_calibration.py per calibrare automaticamente i valori grayscale # oppure modifica manualmente i valori di riferimento con il seguente codice # px.set_line_reference([1400, 1400, 1400]) current_state = None px_power = 10 offset = 20 last_state = "stop" def outHandle(): global last_state, current_state if last_state == 'left': px.set_dir_servo_angle(-30) px.backward(10) elif last_state == 'right': px.set_dir_servo_angle(30) px.backward(10) while True: gm_val_list = px.get_grayscale_data() gm_state = get_status(gm_val_list) print("outHandle gm_val_list: %s, %s"%(gm_val_list, gm_state)) currentSta = gm_state if currentSta != last_state: break sleep(0.001) def get_status(val_list): _state = px.get_line_status(val_list) # [bool, bool, bool], 0 significa linea, 1 significa sfondo if _state == [0, 0, 0]: return 'stop' elif _state[1] == 1: return 'forward' elif _state[0] == 1: return 'right' elif _state[2] == 1: return 'left' if __name__=='__main__': try: while True: gm_val_list = px.get_grayscale_data() gm_state = get_status(gm_val_list) print("gm_val_list: %s, %s"%(gm_val_list, gm_state)) if gm_state != "stop": last_state = gm_state if gm_state == 'forward': px.set_dir_servo_angle(0) px.forward(px_power) elif gm_state == 'left': px.set_dir_servo_angle(offset) px.forward(px_power) elif gm_state == 'right': px.set_dir_servo_angle(-offset) px.forward(px_power) else: outHandle() finally: px.stop() print("stop and exit") sleep(0.1) **Come funziona?** Questo script Python controlla un robot Picarx utilizzando sensori di scala di grigi per la navigazione. Ecco una suddivisione delle sue componenti principali: * Importazione e Inizializzazione: Lo script importa la classe Picarx per il controllo del robot e la funzione sleep dal modulo time per aggiungere dei ritardi. Viene creata un'istanza di Picarx, e c'è una linea commentata che mostra un'inizializzazione alternativa con pin specifici per i sensori di scala di grigi. .. code-block:: python from picarx import Picarx from time import sleep px = Picarx() * Configurazione e Variabili Globali: ``current_state``, ``px_power``, ``offset`` e ``last_state`` sono variabili globali utilizzate per tracciare e controllare i movimenti del robot. ``px_power`` imposta la potenza del motore, e ``offset`` viene utilizzato per regolare l'angolo di sterzata. .. code-block:: python current_state = None px_power = 10 offset = 20 last_state = "stop" * Funzione ``outHandle``: Questa funzione viene chiamata quando il robot deve gestire uno scenario "fuori linea". Regola la direzione del robot in base a ``last_state`` e controlla i valori del sensore di scala di grigi per determinare il nuovo stato. .. code-block:: python def outHandle(): global last_state, current_state if last_state == 'left': px.set_dir_servo_angle(-30) px.backward(10) elif last_state == 'right': px.set_dir_servo_angle(30) px.backward(10) while True: gm_val_list = px.get_grayscale_data() gm_state = get_status(gm_val_list) print("outHandle gm_val_list: %s, %s"%(gm_val_list, gm_state)) currentSta = gm_state if currentSta != last_state: break sleep(0.001) * Funzione ``get_status``: Interpreta i dati del sensore di scala di grigi (``val_list``) per determinare lo stato di navigazione del robot. Lo stato del robot può essere 'forward', 'left', 'right' o 'stop', a seconda di quale sensore rileva la linea. .. code-block:: python def get_status(val_list): _state = px.get_line_status(val_list) # [bool, bool, bool], 0 significa linea, 1 significa sfondo if _state == [0, 0, 0]: return 'stop' elif _state[1] == 1: return 'forward' elif _state[0] == 1: return 'right' elif _state[2] == 1: return 'left' * Ciclo Principale: Il ciclo ``while True`` controlla continuamente i dati del sensore di scala di grigi e regola di conseguenza i movimenti del robot. A seconda dello ``gm_state``, imposta l'angolo di sterzata e la direzione del movimento. .. code-block:: python if __name__=='__main__': try: while True: gm_val_list = px.get_grayscale_data() gm_state = get_status(gm_val_list) print("gm_val_list: %s, %s"%(gm_val_list, gm_state)) if gm_state != "stop": last_state = gm_state if gm_state == 'forward': px.set_dir_servo_angle(0) px.forward(px_power) elif gm_state == 'left': px.set_dir_servo_angle(offset) px.forward(px_power) elif gm_state == 'right': px.set_dir_servo_angle(-offset) px.forward(px_power) else: outHandle() * Sicurezza e Chiusura: Il blocco ``try...finally`` garantisce che il robot si fermi quando lo script viene interrotto o completato. .. code-block:: python finally: px.stop() print("stop and exit") sleep(0.1) In sintesi, lo script utilizza i sensori di scala di grigi per navigare il robot Picarx. Legge continuamente i dati del sensore per determinare la direzione e regola il movimento e la sterzata del robot di conseguenza. La funzione ``outHandle`` fornisce logica aggiuntiva per situazioni in cui il robot deve correggere significativamente il proprio percorso.