ROBOTICA

video
immagini
papers
progettati
costruiti
toolbox
vrml
simulatori

links

 

Papers
meccanica
sistemi
documents

Capitolo 21° Interpolatori e prima semplice animazione Capitolo 23°

Chiariamo ora l’ultimo concetto che ci serve per realizzare una animazione. Abbiamo a disposizione un comando (ROUTE) per passare il contenuto di un nodo ad un altro nodo e abbiamo un nodo TimeSensor che scandisce il tempo. Quello che ci servirebbe a questo punto sarebbe un nodo che presenti valori diversi a seconda del trascorrere del tempo, in modo tale che questi valori possano poi essere spediti al nodo da animare. Nel nostro caso la sequenza di valori va spedita al campo translation del nodo Transform che contiene il cubo che vogliamo animare. Il meccanismo che ancora ci manca viene reso disponibile da vrml con gli interpolatori.

Un nodo interpolatore riceve in ingresso un parametro dipendente dal tempo e manda in uscita un valore dipendente a sua volta dal tempo.

Vediamo un semplice esempio per chiarirci le idee.

DEF posizione PositionInterpolator {
  key [ 0  .5 1 ]
  keyValue [ 1 0 0, 2 0 0, 5 0 0 ]
}

Affinchè l’interpolatore possa funzionare occorre aver definito un nodo TimeSensor.

DEF tempo TimeSensor {
   cycleInterval 10
   enabled TRUE
   loop TRUE
   startTime 1
}

Inoltre dobbiamo collegare il trascorrere del tempo con l’interpolatore in questione. Dobbiamo quindi usare un comando ROUTE.

ROUTE tempo.fraction_changed TO posizione.set_fraction

Da dove sbucano i campi fraction_changed e set_fraction ? Basta fare riferimento alle specifiche dei nodi e si vedrà che questi campi sono propri di questi nodi e che hanno un tipo di interfaccia appropriato per l’operazione effettuata.

Analizziamo in dettaglio quello che abbiamo appena scritto. Abbiamo definito un nodo interpolatore, il cui funzionamento sarà spiegato tra breve. Inoltre abbiamo creato un orologio che segna il trascorrere del tempo. Abbiamo infine collegato il campo fraction_changed del nodo ‘tempo’ al campo set_fraction del nodo ‘posizione’. Non abbiamo dichiarato esplicitamente questi due campi nei nodi, ma essi esistono dal momento in cui il nodo viene creato.

Fraction_changed contiene la frazione di tempo trascorsa rispetto ad un ciclo (in questo caso di 10 secondi). Quindi il campo fraction_changed conterrà un valore compreso tra 0 e 1, con 0 rappresentante l’inizio del ciclo e 1 la fine.

Questo campo emesso dal nodo ‘tempo’, va a settare un campo all’interno del nodo interpolatore. Questo campo, che dipende appunto dal tempo, viene usato per calcolare la nuova posizione. Questa viene calcolata interpolando tra i due valori contenuti nel campo keyValue corrispondenti ai due estremi dell’intervallo di frazioni nel campo key in cui fraction_changed va a cadere.

Per cui si vede che al tempo iniziale, dove fraction_changed è uguale a 0, l’interpolatore emetterà la posizione 1 0 0. Per una frazione di tempo pari a 0.5 (e quindi dopo 5 secondi) la posizione sarà 2 0 0. Per frazioni intermedie l’interpolatore calcolerà posizioni intermedie tra 1 0 0 e 2 0 0. Settando di volta in volta il campo translation del nodo Transform con il valore calcolato dall’interpolatore abbiamo l’animazione.

Dunque manca un ultimissimo tocco. Legare l’uscita del nodo interpolatore con il campo translation. Basta aggiungere :

ROUTE posizione.value_changed TO cubo.set_translation

Et voilà. L’animazione è completata.

Riportiamo qui il sorgente completo.

#VRML V2.0 utf8
#semplice animazione. Versione 1
DEF cubo Transform {
  translation -1 0 0
  children [
    Shape {
      appearance Appearance {
        material Material { diffuseColor 1 0 0 }
      }
      geometry Box { size 1 1 1 }
    }
  ]
}
DEF tempo TimeSensor {
  cycleInterval 5
  enabled TRUE
  loop TRUE
  startTime 1
}
DEF posizione PositionInterpolator {
  key [0 .5 1]
  keyValue [-1 0 0, 0 0 0, 1 0 0]
}
ROUTE tempo.fraction_changed TO posizione.set_fraction
ROUTE posizione.value_changed TO cubo.set_translation
 
 cubo animato  

E con questo la nostra prima animazione è completata. Prima di terminare questo paragrafo osserviamo però (e l’ideale sarebbe appunto provare sulla macchina l’esempio) che il cubo si sposta dalla posizione -1 0 0 a 1 0 0 ; quando però deve ricominciare la sequenza si ha che il cubo riparte da -1 0 0, creando un fastidioso salto. L’ideale sarebbe far rimbalzare il cubo da sinistra a destra e viceversa.

Per fare questo possiamo modificare leggermente l’interpolatore nel modo seguente.

DEF posizione PositionInterpolator {
  key [0 .5 1]
  keyValue [-1 0 0, 1 0 0, -1 0 0]
}

In questo modo il cubo si sposta da sinistra a destra e viceversa in 5 secondi e poi riprende. Se vogliamo mantenere la velocità dell’esempio precedente basta impostare cycleinterval a 10 secondi.

Si noti come l’ultimo valore del campo keyValue va a matchare il primo. Questo è indispensabile per avere continuità nel moto, in quanto 1 e 0 sono in pratica lo stesso istante.

Da ultimo se riconsideriamo la prima versione, si noti che non era necessario introdurre 3 valori nel campo key e keyValue. Infatti la posizione intermedia 0 0 0 per una frazione pari a 0.5 sarebbe stata calcolata automaticamente dall’interpolatore stesso.

Se viceversa voglio impostare diverse velocità o cammini più complessi allora devo aumentare i punti su cui basare l’interpolazione.

Con questa spiegazione possiamo considerare quasi conclusa la parte di animazione con mezzi forniti direttamente da vrml. Nella prossima sezione vedremo un altro esempio e altri tipi di interpolatori.

Procederemo poi a considerare la possibilità di creare animazioni e comportamenti più complessi usando scripts java. Solo pochi cenni saranno rivolti all’uso di scripts CGI e all’interfacciamento con java.

Già con i mezzi a disposizione in questo momento si possono creare mondi decisamente interessanti. Ovviamente le animazioni saranno molto più complesse di quella rappresentata qui come esempio, ma a livello concettuale non ci sarà niente di nuovo ; semplicemente si avranno percorsi più articolati e complicati.