Indice    Avanti    Indietro




12. Cibernetica
         Istruzioni esaminate: bk, setheading, pos, distance, ifelse


Per chiarire la funzione del messaggio nell'uomo, confrontiamo l'attività umana con un'attività profondamente diversa, e cioè quella delle figurine che danzano sulla sommità di un carillon. Le figurine danzano secondo un modello, ma un modello predisposto in cui la loro attività passata non ha praticamente alcuna influenza sul modello della loro attività futura. C'è un messaggio, è vero: ma si tratta di un messaggio che va dal meccanismo del carillon alle figurine e si esaurisce lì. Nelle figurine stesse non vi è traccia di comunicazione con il mondo esterno, tranne quello della comunicazione univoca con il carillon. Esso sono cieche, sorde e mute e non possono in nulla modificare la loro attività dallo schema predisposto nel modello convenzionale.

Norbert Wiener

Il programma di una "tartaruga geometrica" specifica l'effettivo movimento in senso geometrico: avanza di tanto, volta a destra di tanto e così via. Il programma di una "tartaruga cibernetica" potrebbe in effetti dire: trova una luce e raggiungila. Naturalmente per potere effettivamente "dire" questo occorre qualcosa di più di un semplice sensore; occorrono le idee necessarie per utilizzare i sensori in modo da fornire alla macchina la capacità di raggiungere un obiettivo. Il programma non segue più uno "schema" ma ora "emerge". Non appena i bambini cominciano ad utilizzare questa programmazione emergente, entrano nel mondo della cibernetica.

Seymour Papert

Per il momento la realizzazione delle nostre procedure è stata guidata dal principio matematico o, se volete, geometrico della precisione. Pensate ad esempio alla procedura per tracciare un quadrato. Raggiungiamo il nostro obiettivo solo se siamo in grado di comunicare alla tartaruga gli esatti passi della costruzione: avanza di tanto, ruota a destra di 90° e così via. Ora affronteremo un terreno completamente diverso. Immaginate che la nostra tartaruga debba raggiungere del cibo guidata dal suo olfatto. La tartaruga non conosce l'esatta posizione del cibo e deve procedere alla luce di due sole informazioni: l'odore del cibo è più forte, l'odore del cibo è meno forte. Come possiamo realizzare un programma di questo tipo? L'idea fondamentale che sta alla base della "tartaruga cibernetica" è quella della retroazione (feedback): le azioni della tartaruga, cioè i suoi spostamenti, diventano fonte di informazione e condizionano le azioni successive (il passato influenza il futuro).

Esaminiamo in dettaglio le varie procedure che costituiscono il nostro programma. Prima di tutto vogliamo disporre in modo casuale il cibo nel mondo della tartaruga cioè sullo schermo; rappresenteremo il cibo con una piccola croce. Dovremo inoltre tener conto della posizione del cibo in modo tale che sia possibile valutare se la tartaruga si avvicina o si allontana dal cibo e quindi se l'odore è più forte o meno forte. Ecco le procedure

to cibo
   setheading 0
   repeat 4 [fd 4 bk 4 rt 90]
end

to disponi_cibo_a_caso
   cs
   pu
   rt (1+random 360)
   fd (200+random 200)
   pd
   cibo
   make "PosCibo pos
   pu
   home
   pd
   make "d distance :PosCibo
end

Nella procedura cibo, che serve a tracciare una piccola croce nel punto in cui la tartaruga si trova, trovate due nuovi comandi. Il comando setheading imposta in modo assoluto l'orientamento della tartaruga (ad esempio setheading 0 la orienta verso nord, qualunque sia l'orientamento precedente e setheading 90 la orienta verso est). Il comando bk (backward) serve a far indietreggiare la tartaruga di un certo numero di passi (ad esempio bk 4 equivale a fd -4).

La procedura disponi_cibo_a_caso porta la tartaruga in un punto a caso dello schermo e qui "dispone" il cibo (cioè chiama la procedura cibo); lo spostamento casuale è garantito dal comando random di cui abbiamo già parlato nel numero 11 (si effettua una rotazione casuale tra 1 e 360° e un avanzamento casuale tra 200 e 399 passi). Inoltre viene assegnata alla variabile PosCibo la posizione del cibo (cioè la posizione in cui è stata tracciata la croce); la posizione attuale della tartaruga viene fornita dal comando pos che ha in uscita la lista delle coordinate cartesiane del punto. Quindi si riporta la tartaruga nella "tana" e da qui, poi, inizierà la ricerca del cibo. Nella variabile d viene invece salvata la distanza attuale della tartaruga dal cibo; tale distanza viene fornita dal comando distance che ha in input il punto dal quale si vuole valutare la distanza. E' importante capire che il valore della variabile d sarà continuamente aggiornato quando la tartaruga inizierà a muoversi (grazie alla procedura cerca_cibo di cui parleremo tra poco) mentre il valore della variabile PosCibo è assegnato una volta per tutte. Ecco le altre procedure che ci servono

to sensore
   ifelse (distance :PosCibo) > :d ~
       [output "odore_meno_forte] ~
       [output "odore_più_forte]
end

to cerca_cibo
   fd 1
   if sensore = "odore_meno_forte [rt 30]
   make "d distance :PosCibo
   wait 1
   cerca_cibo
end

to start
   disponi_cibo_a_caso
   cerca_cibo
end

Nella procedura sensore trovate due nuove istruzioni: ifelse e output. L'istruzione ifelse funziona così: se una certa condizione è verificata allora viene eseguito il primo blocco di istruzioni tra parentesi quadre altrimenti viene eseguito il secondo blocco. Il comando output serve a mettere in uscita qualcosa (un numero, una parola, una lista) e a interrompere la procedura in cui si trova. Ecco allora che la procedura sensore, ogni volta che viene chiamata, valuta la distanza attuale della tartaruga dal cibo, la confronta con la distanza d precedentemente salvata e fornisce in uscita (output):

  • la stringa odore_meno_forte se la tartaruga si è allontanata dal cibo, cioè se la distanza attuale è maggiore di d (questa è la condizione);

  • la stringa odore_più_forte in caso contrario (notare che il sensore fornisce odore_più_forte anche se la distanza attuale è uguale a d cioè se la tartaruga si mantiene alla stessa distanza dal cibo).

Esaminiamo ora la procedura cerca_cibo, la procedura ricorsiva che costituisce il cuore del nostro programma. Ecco cosa fa:

  1. la tartaruga avanza di un passo (quindi cambia, in generale, la distanza dal cibo rispetto alla posizione precedente)

  2. se l'odore è meno forte (e solo in questo caso) la tartaruga ruota a destra di 30° (qui, notate, entra in gioco il sensore e qui entra in gioco la retroazione: la posizione passata influenza la posizione futura)

  3. si salva nella variabile d l'attuale distanza dal cibo (come si è già detto la variabile d viene continuamente riaggiornata)

  4. si crea una pausa di 1/60 di secondo

  5. si ritorna al passo 1

La procedura start, infine, non fa altro che chiamare nell'ordine disponi_cibo_a_caso e cerca_cibo ed è quella con cui avvieremo il programma. Bene, abbiamo finito. Ma il programma funzionerà? La tartaruga raggiungerà in ogni caso il cibo? Che traiettoria seguirà? Non ci resta che provare. La schermata a fianco mostra una disposizione del cibo e il percorso (a spirale!) per raggiungerlo.

Ora qualche osservazione. Prima di tutto: il nostro programma non ha una condizione d'arresto perciò la tartaruga, dopo avere trovato il cibo, continuerà a girarci intorno, all'infinito, a causa della chiamata ricorsiva di cerca_cibo. Dovremo interrompere il programma mediante il pulsante "Halt". Oppure potremo inserire l'istruzione

if :d < 5 [stop]

tra il terzo e il quarto passo della procedura cerca_cibo (provate).

Osserviamo inoltre che ci sono due dati che potremo modificare nel nostro programma: la rotazione effettuata (per il momento è di 30°) e l'avanzamento effettuato (per il momento è di 1 passo). La schermata a fianco mostra la traiettoria nel caso in cui la rotazione sia di 10° e l'avanzamento di 0,5. La traiettoria è ancora a spirale ma più arrotondata, le correzioni di rotta sono di minor entità e la tartaruga fa molti più giri per raggiungere il cibo (quindi impiega più tempo, la convergenza è meno rapida). Fate voi altri esperimenti modificando i dati e cercate di spiegare quello che succede (avrete delle sorprese).



Ecco infine alcune considerazioni sulla traiettoria. Per molti dei valori dei parametri rotazione e avanzamento (ma non per tutti) la traiettoria è una spirale. E, per di più, si tratta di una stupenda spirale equiangolare (o logaritmica). Cerchiamo di capire riferendoci alla prima spirale considerata. Osservate la figura a fianco. Quando la tartaruga percorre il tratto AB, la sua distanza dal cibo va diminuendo fino a quando, arrivata in B, la sua direzione è perpendicolare al raggio che va dal cibo a B (qui la distanza è minima, se la tartaruga continuasse ad avanzare nella stessa direzione, la distanza comincerebbe ad aumentare); è a questo punto che il sensore impone alla tartaruga di correggere la rotta con una rotazione di 30°.









Da ciò segue che tutti i triangoli della figura a fianco (due sono colorati) sono simili essendo triangoli rettangoli con un angolo di 60°.



Un raggio che parta dal cibo intersecherà la spirale in più punti; ad esempio il raggio viola della figura a fianco interseca più segmenti della spirale e forma con essi angoli uguali (perché i segmenti intersecati sono paralleli e gli angoli corrispondenti). Questa è esattamente la proprietà che caratterizza le spirali equiangolari.

Ora chiediamoci: la traiettoria a spirale è stata da noi esplicitamente programmata? Ed è stata da noi programmata la straordinaria regolarità della spirale equiangolare? No, assolutamente. La regolarità "emerge" dal programma. La nostra tartaruga è guidata da un'unica semplice regola: se l'odore del cibo è meno forte effettua una rotazione.

La spirale equiangolare è una forma che si rintraccia spesso in natura: l'immagine seguente mostra uno stupendo nautilus.