• Non ci sono risultati.

Capitolo 4

N/A
N/A
Protected

Academic year: 2021

Condividi "Capitolo 4"

Copied!
23
0
0

Testo completo

(1)

51

Capitolo 4

Implementazione dei pattern di movimento per il mock-up con cavi

longi-trasversali

In questa parte del lavoro di tesi sono stati sperimentati vari pattern di attivazione dei motori per il mock-up con 40 cavi. Il lavoro si è svolto principalmente in tre parti: adattamento del software al funzionamento con tredici motori; simulazione di movimento di reaching mantenendo invariata la struttura del software; modifica del programma stesso.

4.1 Passaggio da controllo di quattro motori a controllo di tredici motori

Il software originario era in grado di attuare solo quattro servo motori, mentre il setup per attuare il mock-up a 40 cavi ne richiede almeno 13. È necessario, infatti, poter azionare indipendentemente i 9 cavi longi-trasversali ed i 4 cavi che simulano i muscoli longitudinali puri.

Dato che il software era stato predisposto per una modifica in tal senso, poche correzioni sono state sufficienti. L’operazione è stata fatta nel namespace Common. In tale parte del programma, infatti, è possibile selezionare il numero massimo di motori ed il tipo di setup da utilizzare. Esiste, infatti, il comando al preprocessore “#define max num motors” che può essere settato ad un valore massimo di 13.

Si tratta, in termini semplici, di un programma che legge il nostro listato prima del compilatore C, ed esegue certe trasformazioni permettendoci di scrivere del codice più vicino al nostro modo di pensare che a quello del compilatore, e più leggibile.

(2)

52

Possiamo mandare dei comandi al pre processore iniziando una riga con il segno diesis (o cancelletto: il simbolo #).

Poiché nel resto del programma tutti i riferimenti al totale dei motori è dato direttamente dal parametro “max num motors” altre modifiche si sono rese non necessarie. Il resto del programma non ha necessitato di ulteriori modifiche visto che i valori dei comandi ai servo motori erano stati messi in un vector (elemento del linguaggio C++; è un tipo di contenitore di sequenze di elementi. I suoi elementi sono ordinati seguendo una sequenza lineare ben precisa. Esso si adatta automaticamente al numero di elementi esistenti e non richiede che il valore degli elementi rimanga lo stesso).

Come prima prova per verificare l’efficacia della modifica software i motori sono stati connessi agli slot corrispondenti e mandati allo zero comandatogli dalla parte di programma fissata nella memoria Flash del microcontrollore. I motori in numero pari hanno girato l’albero motore fino a portarsi in posizione corrispondente al comando motore di duty cycle del 5.5%. I motori dispari, invece, hanno girato il loro albero motore fino a portarsi alla posizione corrispondente al comando motore di duty cycle del 9.5%.

Dando semplici comandi ai motori stessi dal namespace MotionGenerator si è osservato che i motori rispondono e si attivano proporzionalmente al comando dato.

Una volta testata le funzionalità di base del nuovo set-up il mock-up con i cavi longi-trasversali è stato fissato alla piattaforma e connesso ai servo motori. Durante l’attivazione del mock-up a 40 cavi è stato osservato che per i movimenti che coinvolgevano solo quattro motori non si riscontravano problemi. L’attivavano di più di quattro motori, invece, portava ad un comportamento instabile: sporadicamente il sistema si bloccava fermando tutti i motori ed il software richiedeva un arresto esterno manuale.

(3)

53

Dopo alcune considerazioni è stato individuato il problema nella parte di programma nel

namespace ActuatingLoop che regola il tempo impiegato a far finire il ciclo while al suo

interno. Il programma era strutturato in modo da registrare il valore temporale corrispondente al momento in cui il ciclo inizia e il valore temporale che corrisponde alla fine del ciclo. Al secondo valore veniva sottratto il primo ottenendo il tempo necessario ad eseguire il ciclo. Il tipo di variabile dove erano allocati tali valori, però, non aveva abbastanza bit di spazio per consentirne l’inserimento. A causa di ciò a volte il risultato veniva scritto in maniera sbagliata facendo sì che la differenza a volte risultasse negativa. Per evitare tale evenienza, è stato aggiunto un ciclo if, il quale consente di continuare l’esecuzione dei comandi nel ciclo while solo in presenza di valori dei tempi e della differenza temporale maggiori di zero.

Grazie a tale modifica è stato possibile eseguire dei pattern di attivazione che coinvolgessero tutti i 13 motori di cui è composto il setup. La modifica apportata però, non può evitare che in presenza di valori non accettabili si debba aspettare un ciclo in cui tali parametri siano all’interno del range tollerato per ottenere l’attivazione. Questo fa si che insorgano tempi morti che però, visti i bassi tempi di elaborazione genera ritardi quasi ininfluenti.

Motore Cavo corrispondente

0 T2 1 T9 2 T3 3 Longitudinale di sinistra 4 Longitudinale di destra 5 T1 6 T8 7 T4 8 T6 9 Longitudinale basso 10 T5 11 T7 12 Longitudinale alto

Tab. 4.1 Corrispondenza tra cavi e motori. I riferimenti relativi ai longitudinali si riferiscono ad una vista del mock-up dalla parte della base

(4)

54

I pattern di attivazione devono tenere conto delle corrispondenze tra servo motori e cavi. Infatti, i cavi devono essere disposti in modo da avere un percorso più rettilineo possibile e si allaccino al servo motore più vicino. Viene riportata una tabella che mette in evidenza la corrispondenza che si è creata (Tab.4.1).

4.2 Prove sperimentali con prima modifica software

Una volta assicurato il funzionamento ottimale dei tredici servo motori si è passati alla fase di riproduzione del movimento di reaching tipico del polpo. L’analisi dello stato dell’arte e di numerosi video su questo tipo di movimento ha evidenziato la presenza di diverse fasi. Il

reaching, infatti, inizia con un movimento di retroflessione in cui il braccio viene portato

all’indietro mantenendo la parte aborale del braccio vicino al corpo. Il braccio assume una forma ad ansa e la parte distale è ripiegata in modo da poggiare sulla base del braccio come si può osservare in Fig. 4.1. In seguito il braccio viene steso grazie ad un onda di attivazione che si propaga dalla base alla punta del braccio secondo una delle due teorie di realizzazione dell’onda di stiffening riportate nel Capitolo 2. Mentre la piega si propaga lungo il braccio fino all’apice, la parte prossimale già investita dallo stimolo, rimane rigida ed estesa.

(5)

55

La prima parte del movimento viene riprodotta dall’attivazione del servo motore corrispondente al cavo longitudinale alto. A seconda del valore in input al motore il braccio viene alzato in modo differente. Se l’impulso al servo motore ha duty cycle pari al 5.95% il braccio si retro flette, ma la punta (non attuata) rimane parallela al braccio stesso. Se l’impulso ha un duty cycle del 6.1% la retroflessione è tale da creare un’ansa più accentuata ed un principio di arrotolamento. Il servo motore corrispondente al cavo longitudinale inferiore viene rilasciato mentre il cavo longitudinale superiore viene teso e tirato. In questo modo il movimento del cavo longitudinale alto non viene ostacolato dal cavo opposto suo antagonista. Per ottenere questo effetto il cavo inferiore è stato avvolto sulla puleggia nel verso opposto a quello usuale. In tal modo lo stesso movimento dell’albero motore dell’attuatore porta alla diminuzione della tensione sul cavo invece che al suo aumento. Questa soluzione si è resa necessaria poiché i motori hanno una posizione di zero non modificabile da software, ma modificabile solo dalla parte di memoria Flash del microcontrollore che è stata bloccata (vedi descrizione del microcontrollore nel Capitolo 3). Non occorre, però, che il cavo longitudinale inferiore venga attivato della stessa ampiezza con il quale è attivato il suo opposto. Basta infatti che il motore corrispondente venga attivato con un duty cycle del 5.65%. Un tempo di attivazione maggiore si è dimostrato tanto inutile quanto dannoso, poiché l’eccessiva rotazione fa perdere aderenza sulla puleggia e fa si che il cavo formi un’ansa tale da determinarne l’uscita dall’incavo della puleggia. Il fatto che l’attivazione necessaria per tendere il cavo inferiore non sia la stessa di quella utilizzata per il cavo longitudinale superiore induce a pensare che il materiale stesso compensi l’attivazione unilaterale con una deformazione.

La seconda fase del movimento viene riprodotta grazie all’attivazione sequenziale dei gruppi di cavi longi-trasversali partendo da quello più prossimale per finire con quello più distale. In un primo momento si è provato ad attivare tutte le sezioni di strizione con le medesime attivazioni. In tal maniera, però, non veniva riprodotta la tipica onda di stiffening desiderata visto che non si osservava il contributo alla distensione del braccio dall’attivazione delle sezioni di strizione ma l’estensione era dovuta alle sole caratteristiche del materiale. Si è quindi provato ad attivare le sezioni di strizione con attivazioni di maggiori man mano che ci si allontana dalla base del braccio. L’ampiezza delle attivazioni cresce proporzionalmente alla distanza dalla base, vedi Tab. 4.2. Questa correzione è una diretta conseguenza dell’accorciamento lungo l’asse longitudinale del mock-up in seguito all’attivazione dei cavi longi-trasversali. Infatti, i cavi devono essere attivati sia per permettere di stringere la sezione radialmente sia per compensare il piccolo allentamento conseguenza della

(6)

56

accorciamento della parte del mock-up a monte. I fermi dei cavi longi-trasversali, in seguito all’attivazione, agiscono sulla superficie del mock-up e la deformano localmente a causa della tensione esercitata radialmente dal cavo . Tale effetto, però, si nota meglio nei gruppi di attivazione prossimali. Questo suggerisce che, dove la sezione è maggiore, la deformazione in direzione radiale cresce.

Queste due fasi del movimento vengono esplicate nel controllo grazie alla definizione delle attivazioni nel namespace MotionGenerator. È stata, infatti, cambiata la parte centrale del codice in MotionGenerator.cpp per permettere di muovere tutti i motori. La struttura globale ed il funzionamento di MotionGenerator.cpp, però, sono stati mantenuti pressoché inalterati. Il software divide il movimento in 9 parti. Nella prima il longitudinale superiore viene tirato, rilasciando contemporaneamente il longitudinale inferiore. In seguito entrambi i motori vengono mandati a zero e nello stesso momento comincia la contrazione del primo gruppo di longi-trasversali, poi del secondo e così via fino ad arrivare all’ultimo (Tab. 4.2). Una volta che l’attivazione sequenziale viene esaurita tutti i motori vengono rimandati a zero e l’intera sequenza di attivazione viene ripetuta.

Evitando di riportare a zero il parametro che fa le veci dell’indicazione temporale del programma (ctr, vedi Appendice A) si fa sì che il ciclo non venga ripetuto dall’inizio e che si rimanga nell’ultima porzione temporale del codice in MotionGenerator.cpp.

Per scongiurare l’eventualità di un intervallo temporale (looptime) non sufficiente a portar a termine le attivazioni dei motori si era provveduto ad aumentarlo. Dal valore originario di

Gruppo di cavi longi-trasversali Duty cycle dell’attivazione corrispondente 1 5.7 % 2 5.735 % 3 5.8 % 4 5.875 % 5 non attivato 6 5.975 % 7 6.025 % 8 6.075 % 9 non attivato

Tab. 4.2 attivazione per i servo motori collegati ai gruppi di strizione trasversali utilizzati. Notare che i valori sono crescenti all’allontanarsi dalla base del mock-up. Alcuni gruppi non sono attivati per un problema riguardo al parametro looptime spiegato nel paragrafo successivo.

(7)

57 looptime di 50000 microsecondi si era passati a 100000 microsecondi (la sua definizione è

in Common.hpp ed è esplicata come comando al preprocessore). La modifica di tale parametro si rifletteva nella parte operativa sul codice che da l’input ai servomotori,

MotionGenerator.cpp. Il codice in MotionGenerator.cpp. è composto da una struttura del

tipo if, else if, else. La condizione di questi comandi if riguardavano intervalli temporali da confrontare con la quantità ctr*looptime*10, come si vede nell’esempio qui riportato.

else if ( (double)(ctr*loopTime) > (double)tw && (double)(ctr*loopTime) <= (0.25*(double)tp + (double)tw) ) { setPoints.at(0) = amplitude; setPoints.at(1) = 0; setPoints.at(2) = 0; setPoints.at(3) = 0;

printf("\n\n\nMotor 1 set\n\n"); }

L’aumento del parametro looptime faceva sì che il passo con cui variava la quantità ctr*looptime*10 era maggiore dei range temporali delle condizioni dei comandi if. Dato che la loro condizione non veniva mai a verificarsi alcune porzioni di questo programma venivano saltate e, di conseguenza, alcuni gruppi di strizione non venivano mai attivati, come si vede in Tab.4.2 nelle sezioni 5 e 9. Si è cercato di diminuire il valore del parametro

looptime gradualmente ma venivano comunque saltate delle porzioni di codice. Si è quindi

riportato il valore di looptime a 50000 microsecondi, valore che comunque non impedisce di portar a termine le attivazioni dei motori come si era temuto.

Sono stati creati, a questo punto, alcuni video (vedi Fig. 4.2) per documentare le varie prove

Fig. 4.2 Immagine dimostrativa presa da uno dei video realizzati

(8)

58

sperimentali. Nella serie di video si vedono il movimento risultante dall’attivazione dei soli gruppi di cavi longi-trasversali, il movimento risultante dall’attivazione del solo cavo longitudinale superiore e un video rappresentante l’unione di entrambe le attivazioni. Quest’ultimo tipo di video è stato realizzato sia nella condizione in cui il movimento termina con i cavi ancora tutti attuati sia nel caso in cui i cavi vengono tutti rilasciati fino a che i servo motori non sono alla posizione di zero.

4.3 Modifica software per ottimizzare i parametri

Nonostante le modifiche apportate, si sono resi necessari ulteriori cambiamenti per risolvere problemi riscontrati negli esperimenti precedenti ed ottimizzare alcuni parametri.

Un parametro da ottimizzare è il tempo in cui far muovere la puleggia del motore. Dopo aver dato il comando ai motori si osservano i tempi di risposta: se l’attivazione non è immediata, il tempo da dare va diminuito fino ad arrivare ad una risposta istantanea. Tale ottimizzazione del parametro è stato ottenuta dando i comandi al motore e poi introducendo il comando sWait() che ferma l’attuazione del programma e quindi motore per il tempo in secondi indicato tra parentesi.

Dai dati disponibili sul data sheet dei servo motori si sa che la velocità angolare a regime senza carico è di 1.38 s per 360°.

I secondi necessaria far girare l’albero motore di 1 grado sono pari a: .

 = 0.003833333 

ሾ௦ሿ ሾ௚௥௔ௗ௜ሿ

La proporzione che collega i gradi all’impulso d’ingresso ai motori è: x:800 = 1:1260

Il valore 800 è il range tra gli impulsi temporali al motore massimo e minimo. Il valore di tempo a livello alto massimo è di 1900 microsecondi corrispondente a 3.5 giri della puleggia del servo motore ed al duty cycle del 9.5%. Il valore minimo (1100 microsecondi) del range corrisponde allo zero del motore ed al duty cycle del 5.5%. Il valore 1260 è ottenuto moltiplicando il numero di gradi presenti in un giro (360) per 3.5, numero di giri eseguiti dal servo motore HS-785HB. Il parametro “x” rappresenta il numero di microsecondi con cui attivare il servo motore attraverso il controllo PWM per ottenere il movimento di un grado.

(9)

59

Per ottenere il tempo impiegato perché si abbia il movimento corrispondente ad un comando di 1 microsecondo si usa la formula:

tattivazione = 0.00383333    *       = 0.0060375 

Se si moltiplica il parametro tattivazioneper il numero di microsecondi di attivazione dei motori o duty cycle si ottiene il tempo che il servo motore impiega a far girare la puleggia dell’angolo corrispondente.

Questo dato temporale viene controllato facendo una prova col servo motore. Si da un impulso d’ingresso e si vede se il motore riesce ad arrivare alla fine dell’attivazione in quel lasso temporale. Si nota, però, che il movimento non riesce ad essere completato. Infatti, il ragionamento con cui si è arrivati alla determinazione del tattivazione assume che la velocità sia da subito quella di regime mentre ciò non accade. Questo probabilmente avrà un peso nella contrazione dei longi-trasversali prossimali che hanno attivazioni molto brevi. Per tale ragione si rende indispensabile una prova, per vedere quali sono in realtà i tempi nel caso specifico. Si fa effettuare al servo motore il movimento dalla posizione di zero alla posizione di massimo, cioè si fanno fare 3.5 giri e si cronometra il tempo necessario. Da questa prova si ricava la seguente velocità:

.

 = 0.005 

ሾ௦ሿ ሾ௚௥௔ௗ௜ሿ

A questo punto si procede come sopra per determinare il tempo necessario per completare l’attivazione di 1 microsecondo. tattivazione-nuovo = 0.005    *       = 0.007875 

Tale valore viene moltiplicato per il numero di microsecondi dell’attivazione o duty cycle. Questo viene ripetuto per tutti i comandi motori nel pattern di attivazione.

La determinazione del parametro tattivazione-nuovo, per quanto utile, rispecchia comunque l’attivazione del servo motore senza carico, mentre nella realizzazione del movimento vero e proprio è presente il carico dato dal mock-up. Una determinazione del tempo basata sul comportamento a carico risulta estremamente complessa e dipende da attivazione ad attivazione. Per tale ragione si è preferito variare il parametro che indica l’attivazione del motore durante le prove in modo da non escludere alcuna possibilità di ottimizzazione del

(10)

60

tempo. L’andamento generale del programma è riportato nel diagramma di flusso della pagina seguente. while (1) switch (ch) Tasti sx tastiera Tasto “q”: stop = 0 Chiamata la funzione loop::stop che mette ContinueLoop = (0) V F S while (1) S If (stop = 1) Salva i valori ampli in dati.dat Aumento di ampli (Tab 4.2.1) Tasti dx tastiera Diminuzione di ampli (Tab 4.2.1) chiama Funzione ChangeSetPoints V F thread Actuating Loop v e d e re n e l th re a d E If ContinueLoop =1 E Reset Motori Controllo che ampli (i:1..9)

sia nel range giusto Crea thread

ActuatingLoop

Apre la funzione start di ActuatingLoop i tasto aumento tasto diminuzione 1 k s 2 j d 3 h f 4 m z 5 n x 6 b c 7 o w 8 i e j++ j=-1

(usato nella funzione ChangeSetPoints)

(11)

61

Un'altra modifica importante al programma per ottimizzarne la prestazione è rappresentata dall’eliminazione di un thread nella main, quello relativo a MotionGenerator. Il thread

MotionGenerator era stati inserito esclusivamente per dare i comandi ai motori. Invece, il thread ActuatingLoop serviva per coordinare sia gli input ai motori che i dati dei sensori.

Visto che i sensori non sono presenti in questa versione del setup, mantenere due thread era ridondante e manteneva l’errore riguardo alla temporizzazione a cui si è fatto riferimento nel precedente paragrafo. Infatti, avendo un solo thread non c’è alcun bisogno di far coincidere i tempi dei due cicli while dati dai due thread. Si è quindi tolta dal programma la parte che otteneva i tempi di inizio e fine del ciclo while del thread ActuatingLoop e che, calcolata la differenza tra questi, teneva in sospensione il programma fino che non si era raggiunto un tempo prestabilito, che era lo stesso per entrambi i thread portando così ad una sincronizzazione.

Non essendoci più il thread MotionGenerator i comandi ai motori possono essere semplicemente scritti in una funzione inserita nel thread ActuatingLoop. La funzione in particolare si chiama changesetpoints().

Nel source file ActuatingLoop.cpp si è modificato il range di sicurezza in cui far agire i motori. Infatti, era stato programmato un comando if di sicurezza per cui se il controllo aveva in ingresso ai motori valori di duty cycle superiori al 9.5% li riportava automaticamente a tale valore e se i valori d’ingresso erano inferiori al duty cycle del 5.5% erano invece portati al 5.5%. Per evitare azioni dannose per il mock-up che potrebbero comprometterne l’integrità, il parametro superiore del range è stato cambiato in modo che per valori di duty cycle superiori al 6.3% vengono ricondotti a questo valore.

Il software di controllo è stato ulteriormente modificato per poter aggiornare in tempo reale le larghezze d’impulso e permettere di apprezzare subito il diverso risultato nel movimento di reaching che la variazione di questo parametro determina. Tale modifica fornisce la possibilità di continuare a far eseguire il movimento mentre si esegue un fine-tuning in tempo reale, senza essere costretti a fermare e riavviare il programma ogni volta.

Questo controllo viene implementato nel codice del main attraverso l’impiego del comando

switch (vedi codice sotto riportato).

switch (ch) { case 'a':

(12)

62

{

loop->ampl12=loop->ampl12-5;

printf("Ampiezza diminuita di un incremento\n"); break;

}

case 'l': {

loop->ampl12=loop->ampl12+5;

printf("Ampiezza accresciuta di un incremento\n"); break;

}

In tale parte del codice si esplicita che, nel momento in cui una particolare tasto viene premuto seguito da “invio”, il parametro “ampli”, con i corrispondente al numero del motore, viene aumentato dello 0.025%, che è poi letto come input al controllo PWM. Nel caso riportato nel codice qui sopra il tasto corrisponde alla lettera “a” per una diminuzione ed alla lettera “l” per un aumento. L’impulso a tutti i motori, con questa metodologia, può essere sia aumentato che diminuito in tempo reale. Il parametro “ampli” è inizializzato con valore zero. La variabile “ampli” può essere cambiata anche più volte nella stessa sessione ed ogni volta il valore viene aggiornato in automatico.

Alla larghezza d’impulso “ampli”, che può variare, è aggiunta una componente fissa che è inizialmente del 5.8% per il servo motore corrispondente al cavo longitudinale alto, del 5.65% per il servo motore corrispondente al cavo longitudinale basso, del 5.65% per i tre longi-trasversali più prossimali, del 5.75% per i tre longi-trasversali mediani e del 5.85% per i tre longi-trasversali più distali. Questa componente è stata aggiunta per permettere di partire da valori di base “ad hoc” a cui sia necessario aggiungere solo una piccola componente per poterne ottenere l’ottimizzazione. . La larghezza d’impulso fissa è stata poi cambiata nel corso delle prove.

Per far sì che il motore in ingresso avesse sia il valore fisso sia la parte modificabile in tempo reale viene creata nella funzione changesetpoints() la variabile “ampi”, per tutti i motori, che viene definita come la somma delle due componenti e data in ingresso al controllo PWM del servo motore.

Il controllo è stato composto in modo che il movimento venga ripetuto ciclicamente e che, una volta fermato , i valori delle variabili “ampli” vengano memorizzati nel file dati.dat. Da questo file i valori dei parametri “ampli” vengono copiati e utilizzati all’inizio del successivo ciclo di movimenti di reaching senza però impedire un’ulteriore variazione del parametro “ampli”. La parte di memorizzazione dei parametri “ampli” nel file è eseguita nel

main, specificamente nella parte di programma del comando switch al case ‘q’, che conduce

(13)

63

dati.dat e riportati nel programma nel primo comando if nella funzione changesetpoints() del

source file ActuatingLoop.cpp.

Una volta fatte queste modifiche che rendono più veloce e più efficace il processo di esecuzione delle prove sperimentali si è creata la struttura della funzione changesetpoints(). La funzione è strutturata in tante porzioni temporali quanti sono le sezioni da azionare. Infatti, in ogni porzione viene attivata una specifica sezione di strizione e dopo la sua attivazione viene fermato il programma grazie alla funzione “sWait” che da così il tempo al motore di tirare i cavi di tale sezione. Ecco l’esempio dell’implementazione di una di esse:

float amp0 = 1130 + ampl0; //definizione della larghezza dell’impulso totale d’ingresso al motore

printf("larghezza impulso al trasverso-longitudinale 2 : %f\n",ampl0); titechBoard->writeMotor(0,amp0); //funzione che esegue il comando diretto al motore

sWait(0.007875*200); //funzione che ferma l’attuazione del programma

fino a che il numero di secondi scritto tra parentesi non si è esaurito

In questa parte del programma software si possono ravvisare le variabili descritte nei paragrafi precedenti. Il valore iniziale del parametro da moltiplicare per il valore 0.007875 all’interno della funzione sWait è inizializzato a 200, ma poi viene modificato durante le varie prove sperimentali.

La funzione changesetpoints() è divisa in 12 parti. Nella prima vengono copiati dal file dati.dat i valori “ampli”, nella seconda vengono attivati i motori corrispondenti al cavo longitudinale alto e al cavo longitudinale basso, nella terza è attivato il motore corrispondente al cavo longi-trasversale più prossimale mentre contemporaneamente i cavi longitudinali sono rilasciati. Subito dopo si trovano le parti di programma che attivano in sequenza tutti i motori collegati ai cavi longi-trasversali e nella porzione seguente si da la possibilità di attivare anche i motori collegati ai cavi longitudinali destro e sinistro che, però, di norma vengono sempre lasciati alla posizione di zero, visto che il movimento da riprodurre è planare e non prevede quindi attivazioni che deviano dal piano del video della telecamera frontale. Nell’ultima parte del programma i cavi vengono tutti rilasciati fino ad assumere la loro posizione di zero. Le varie parti della funzione sono riportate nel diagramma di flusso della pagina seguente. Ovviamente, qui viene descritta solo la struttura generale della funzione di attivazione e nei diversi esperimenti viene cambiata come descritto nel protocollo sperimentale.

(14)

64

S

V

F

Funzione ChangeSetPoints del thread ActuatingLoop

E

Carica i valori di ampli (i:1..9) dal file dati.dat ai parametri ampli nel resto del programma

invio comando al Motore longitudinale superiore = ampli + valore di default Motore L-T 1 = ampli + valore di default aspetta esecuzione aspetta esecuzione aspetta esecuzione aspetta esecuzione aspetta esecuzione aspetta esecuzione Motore L-T 2 = ampli + valore di default Motore L-T 3 = ampli + valore di default Motore L-T 4 = ampli + valore di default Motore L-T 5 = ampli + valore di default Motore L-T 6 = ampli + valore di default aspetta esecuzione Motore L-T 7 = ampli + valore di default aspetta esecuzione Motore L-T 8 = ampli + valore di default aspetta esecuzione Motore L-T 9 = ampli + valore di default aspetta esecuzione Motori a zero if (j < 0) (prima esecuzione) R E T R O F L E S S IO N E O N D A D I S T IF F E N IN G

(15)

65

4.4 Protocollo sperimentale

La seguente è una selezione degli esperimenti più significativi nella totalità di quelli portati a termine con le modifiche software sopra specificate. Per avere una casistica completa vengono creati esperimenti con le tre configurazioni di angolo di base sia nel caso dell’attivazione dalla base alla punta sia nel caso dell’attivazione dal quarto gruppo di longi-trasversali. Sono state scelti gli esperimenti in cui l’unico parametro che varia è l’attivazione del cavo longitudinale superiore per comprenderne l’influenza nella dinamica del movimento. Tra le varie versioni sono state scelte quelle attivazioni che danno un movimento qualitativamente più simile al movimento del polpo. Il movimento di reaching viene riprodotto con una retroflessione seguita da un'attivazione sequenziale nel tempo e con valori crescenti dei servo motori relativi ai gruppi longi-trasversali .

Esperimento numero 8: Si attiva il motore collegato al longitudinale superiore con un impulso con duty cycle del 6%, i primi tre cavi longi-trasversali vengono attivati insieme al longitudinale superiore. I tempi vengono ricavati moltiplicando il fattore 0.007875 (ricavato al paragrafo 4.3) per la serie: 75, 75, 80, 80, 80,80 (il primo valore si riferisce a quanto rimane attivato il primo gruppo di longi-trasversali, il secondo valore si riferisce alla durata del secondo gruppo di longi-trasversali e così a seguire), le larghezze d’impulso con cui i longitudinali vengono attivati hanno duty cycle del 5.65% per i primi tre longi-trasversali, di 5.75% per i longi-trasversali 4,5,6 e di 5.85% per gli ultimi tre longi-trasversali. Questi valori sono dati dal programma in default, vengono poi aggiunti degli ulteriori valori che si vanno a sommare a questi. Nel caso di E8 i valori delle attivazioni sono riportati in tabella 4.3.

Motore del longi-trasversale

Duty cycle di default Aumento del duty cycle Valore finale duty cycle 1 5.65% 0% 5.65 % 2 5.65% 0% 5.65 % 3 5.65% 0.125% 5.775% 4 5.75% 0 % 5.75% 5 5.75% 0.125% 5.875% 6 5.75% 0.275% 6.1% 7 5.85% 0.25% 6.05% 8 5.85% 0.175% 6.025% 9 5.85% 0.175% 6.025%

(16)

66

Esperimento numero 15: in questa prova il longitudinale superiore viene portato alla posizione di retroflessione finale in tre tempi evitando di sforzare il cavo nel passare dalla situazione statica a quella dinamica. In questa attivazione il longitudinale superiore è alzato con un impulso con duty cycle del 6% poi aumentato a 6.15% e infine a 6.25%. Il longitudinale superiore non viene rilasciato immediatamente, ma nelle due attivazioni sequenziali successive viene prima portato ad un’attivazione corrispondente ad un duty cycle del 5.95% e poi del 5.75%. I longi-trasversali vengono attivati come indicato nella tabella 4.4:

I tempi vengono ricavati moltiplicando il fattore 0.007875 (ricavato al paragrafo x) per la serie: 5, 5, 10, 10, 15, 15, 20, 20, 20 (il primo valore si riferisce al primo gruppo di longi-trasversali, il secondo valore si riferisce al secondo gruppo di longi-trasversali e così a seguire). In questo caso i tempi di attivazione sono stati diminuiti al massimo, ma, ad una valutazione qualitativa, sembrava che i tempi fossero così brevi da non permettere ai gruppi di longi-trasversali di contrarsi dell’input fornitogli.

Esperimento numero 17: in questo esperimento i parametri per l’attivazione del Motore del

longi-trasversale

Duty cycle di default Aumento del duty cycle Valore finale duty cycle 1 5.65% 0% 5.65 % 2 5.65% 0% 5.65 % 3 5.65% 0.15% 5.8 4 5.75% 0.025 % 5.775% 5 5.75% 0.125% 5.875% 6 5.75% 0.4% 6.15% 7 5.85% 0.35% 6.2% 8 5.85% 0.175% 6.025% 9 5.85% 0.175% 6.025%

Tab. 4.4 Valori da aggiungere alle attivazioni di default del programma per l’esperimento numero 15

Motore del longi-trasversale Duty cycle dell’ attivazione corrispondente 1 5.7 % 2 5.735 % 3 5.8 % 4 5.875 % 5 5.925 % 6 5.975 % 7 6.025 % 8 6.075 % 9 6.125%

Tab. 4.5 Valori da sostituire ai precedenti per le attivazioni di default del programma per l’esperimento numero 17 e per gli esperimenti seguenti. Notare che i valori sono crescenti

(17)

67

longitudinale superiore e dei gruppi di longi-trasversali sono mantenuti invariati rispetto all’esperimento precedente, ma i tempi sono stati variati. I valori da moltiplicare per il coefficiente 0.007875 sono stati incrementati a: 20, 20, 25, 25, 30, 30, 35, 35, 35. Osservando il movimento delle pulegge dei motori questa attivazione sembra non fermare i motori prima che questi possano raggiungere la fine della loro azione rotazionale. Le attivazioni di base dei longi-trasversali vengono cambiate nel modo indicato dalla tabella 4.5.

Esperimento numero 20: L’attivazione del longitudinale superiore corrisponde al duty cycle del 6% inizialmente, poi aumentata nella seconda ripresa, arrivando quindi ad un’attivazione totale con duty cycle di 6.1%. I tempi sono come quelli dell’esperimento numero 17, si vuol quindi testare se il solo cambiamento dell’attivazione del longitudinale superiore cambia significativamente il movimento.

Esperimento numero 21: L’attivazione del longitudinale superiore corrisponde al duty cycle del 6% inizialmente, poi aumentata nella seconda ripresa, arrivando quindi ad un’attivazione totale con duty cycle di 6.1%. Questo cavo non viene rilasciato immediatamente ma gradualmente: è attivato con una larghezza d’impulso corrispondente al duty cycle di 5.95% e poi del 5.75% nella fase successiva. In questo esperimento i primi tre gruppi di longi-trasversali vengono attivati contemporaneamente alla seconda attivazione del longitudinale superiore. In questo modo quando l’onda di attivazione che simula il reaching viene prodotta, ha effetto a cominciare dal quarto gruppo di longi-trasversali. Tale attivazione è ispirata al movimento del polpo come viene descritto in letteratura [3]. Viene infatti riportato che durante il movimento di reaching il segmento prossimale del braccio (la parte tra la piega, cioè il punto di massima curvatura e la base del braccio) non si muove; la parte del braccio dalla base alla piega è quasi rettilinea (Fig 4.3). I tempi di attivazione dei gruppi di longi-trasversali rimasti da attivare sono di 25, 30, 30, 35, 35, 35 (fattori che moltiplicano il coefficiente di 0.007875; il primo valore riguarda il quarto gruppo di longi-trasversali, il secondo valore riguarda il quinto gruppo di longi-trasversali, il terzo valore riguarda il sesto gruppo di longi-trasversali, il quarto valore riguarda il settimo gruppo di longi-trasversali, il quinto valore riguarda l’ ottavo gruppo di longi-trasversali, il sesto valore riguarda il nono gruppo di longi-trasversali).

Esperimento numero 23: Si attiva il motore corrispondente al longitudinale superiore con un duty cycle del 6.2%, si prova quindi l’effetto della massima attivazione tentata, i primi tre cavi trasversali vengono attivati insieme al longitudinale superiore. Poi gli altri

(18)

longi-68

trasversali vengono attivati in sequenza. I tempi sono i medesimi di quelli utilizzati nell’esperimento numero 21.

Negli esperimenti seguenti è stato cambiato l’assetto della piattaforma. L’ estremità della parte verticale della piattaforma è quella a cui viene assicurata la base del mock-up. Tale estremità è regolabile dato che può ruotare su due diversi assi. In questo caso viene ruotata rispetto all’asse entrante del piano di acquisizione video di 30° in senso antiorario (verso il basso).

Esperimento numero 28: Si attiva il motore collegato al longitudinale superiore con un duty cycle del 6%, in seguito si aumenta tale valore fino ad arrivare a 6.1% poi ulteriormente fino al 6.2%. I tempi e l’ampiezza d’attivazione dei gruppi di longi-trasversali sono stati lasciati

Fig. 4.3 Propagazione dell’onda di bending lungo il braccio del polpo nel movimento di

(19)

69

invariati rispetto agli esperimenti precedenti per facilitarne il confronto diretto.

Esperimento numero 29: Questo esperimento è stato ottenuto tenendo tutti i parametri al valore dell’esperimento precedente, ma cambiando l’attivazione del servo motore che aziona il cavo longitudinale superiore che stavolta si ferma ad un duty cycle del 6.1%. Questo perché in questa prova l’interessa è focalizzato sugli effetti della variazione di questo parametro sul movimento.

Esperimento numero 31: In questo caso il servomotore collegato al longitudinale superiore viene fatto funzionare con un duty cycle del 6.2%, anche in questo caso utilizzando un comando in tre tempi. Tale cavo non viene rilasciato tutto in una volta, ma in due passaggi con comando al motore decrescente: uno con un duty cycle del 5.95% ed uno al duty cycle del 5.75%. I tempi totali risultano dal prodotto del parametro fisso (0.007875) con i parametri variabili nel corso delle prove, in questa istanza fissati a: 15, 15, 20, 20, 25, 25, 30, 30, 30 (tali valori si riferiscono ai vari gruppi di longi-trasversali dal primo al nono). I longi-trasversali sono attivati con i parametri di base più l’attivazione addizionale dal file dati.dat riportata nella tabella 5.6

Esperimento numero 32: I parametri per questo esperimento sono stati lasciati invariati rispetto al precedente, ma è stata adottata una tecnica per permettere di realizzare il movimento più velocemente, visto che il movimento di reaching viene realizzato dal polpo in 1-2 sec. Infatti, i gruppi di longi-trasversali hanno tempi di attivazione via via maggiori dal primo all’ultimo. Ciò è causato dal fatto che per i gruppi da attivare dopo il primo si ha bisogno di recuperare la parte di cavo che risulta meno tesa. Questo fenomeno si realizza in quanto l’attivazione della sezione precedente ha deformato la porzione di silicone

Motore del longi-trasversale

Duty cycle di default Aumento del duty cycle Valore finale duty cycle 1 5.7 % 0% 5.7 % 2 5.735 % 0% 5.735 % 3 5.8 % 0.1% 5.9% 4 5.875 % 0.025% 5.9% 5 5.925 % 0.025% 5.95% 6 5.975 % 0.15% 6.125% 7 6.025 % 0.15% 6.175% 8 6.075 % 0.075% 6.15% 9 6.125% 0.075% 6.2%

(20)

70

immediatamente precedente alla sezione stessa rendendola più corta lungo l’asse longitudinale. L’accorciamento della porzione di silicone fa sì che il cavo, che invece mantiene la stessa lunghezza di partenza, risulti più lasco. Tale “recupero” di cavo può esser eseguito all’inizio dell’attivazione del gruppo di longi-trasversali in questione, ma può anche essere eseguito mentre si sta attivando il segmento di attivazione a monte. Per esempio, mentre si sta attivando il terzo gruppo di longi-trasversali contemporaneamente si recupera il cavo del quarto gruppo di longi-trasversali.

Esperimento numero 33: Prova con impulso di attivazione dell’attuatore del longitudinale superiore di duty cycle del 6.1%. Si tengono i primi tre gruppi di longi-trasversali attuati fin dal momento di retroflessione. I valori dei tempi di contrazione dei gruppi dei longi-trasversali vengono creati moltiplicando la costante 0.007875 per il valore dato ad ogni gruppo. Tali valori in questo caso sono di: 15, 15, 20, 20, 25, 25, 30, 30, 30. Le ampiezze dell’impulso di input ai servomotori dei cavi longi-trasversali sono quelle riportate in tabella 4.6.

Esperimento numero 34: stessa attivazione dei longi-trasversali e tempi dell’esperimento numero 33. Il cavo del longitudinale superiore viene questa volta attivato con un impulso al motore corrispondente al duty cycle del 6.2%. poiché in questa prova l’interesse è focalizzato sugli effetti della variazione di questo parametro sul movimento.

Esperimento numero 35: in questo caso il cavo longitudinale superiore viene alzato per portare il braccio in posizione retroflessa e poi rilasciato. È così possibile distinguere le caratteristiche del movimento direttamente imputabili all’attivazione sequenziale dei gruppi di longi-trasversali e quelle che dipendono invece solo dalle proprietà dei materiali, dall’interazione con il mezzo acquoso e dall’ampiezza della retroflessione.

Negli esperimenti seguenti è stato cambiato l’assetto della piattaforma la cui estremità viene ruotata rispetto all’asse sagittale (entrante nel piano video) di 30° in senso orario (verso l’alto).

Esperimento numero 39: questo esperimento vede inizialmente una messa in funzione del servo motore corrispondente al cavo longitudinale superiore di un duty cycle del 6%. Il longitudinale alto, inoltre, viene rilasciato totalmente e non gradualmente. I tempi con cui vengono attivati i gruppi di longi-trasversali corrispondono al valore 0.007875 moltiplicato per il valori 15, 15, 20, 20, 20, 30, 30, 35, 35, 35 (i valori si riferiscono, nell’ordine, dal

(21)

71

gruppo prossimale fino al distale). Le attivazioni per i gruppi di longi-trasversali sono quelle trascritte in tabella 4.6.

Esperimento numero 40: Prova con impulso di attivazione dell’attuatore del longitudinale superiore di duty cycle pari a 6.1%, valore che viene poi diminuito in due scaglioni: prima al 5.95% mentre viene contratto il primo gruppo di quattro longi-trasversali e poi al 5.75% contemporaneamente all’attivazione del secondo gruppo di longi-trasversali. Tutti gli altri parametri sono i medesimi dell’esperimento numero 39.

Esperimento numero 41: In questo caso il servomotore collegato al longitudinale superiore viene fatto funzionare con un duty cycle del 6.2%. Tutti gli altri parametri sono rimasti invariati rispetto a quelli dell’esperimento precedente poiché in questa prova l’interesse è focalizzato sugli effetti della variazione di questo parametro sul movimento.

Esperimento numero 43: Prova con impulso di attivazione dell’attuatore del longitudinale superiore con duty cycle del 6.2%. Si tengono i primi tre gruppi di longi-trasversali attuati fin dal momento di retroflessione. I valori dei tempi di contrazione dei gruppi dei longi-trasversali vengono creati moltiplicando la costante 0.007875 per il valore dato ad ogni gruppo. Tali valori in questo caso sono di: 15, 15, 20, 20, 25, 25, 30, 30, 30. Le ampiezze dell’impulso di input ai servomotori dei cavi longi-trasversali sono quelle riportate in tabella 4.6.

4.4 Modifica software per ottenere più motori attivi contemporaneamente

Fig.4.4 Immagine presa da un video relativo agli esperimenti con

(22)

72

Questo tipo di controllo è stato creato perché i motori possano entrare in funzione con una tempistica indipendente dagli altri. Esso è strutturato definendo una variabile, j, e facendola aumentare nel tempo grazie ad un contatore posto alla fine del comando setPoint per tutti i motori.

La variabile j è inserita all’interno del comando setPoint = che da la larghezza dell’impulso di comando al motore, in modo che all’aumentare della variabile j aumenti anche la larghezza dell’impulso in ingresso al motore in modo proporzionale. In tale controllo tutti i motori si muovono contemporaneamente anche se non partono tutti nello stesso momento. Ogni motore però ha un range ben preciso e fissato a priori per la larghezza d’impulso d’ingresso. Tale range è ottenuto attraverso tre comandi if che si assicurano che l’impulso d’ingresso sia portato almeno al 5.5% (valore minimo) anche nel caso in cui venga dato un comando di grandezza inferiore e che l’impulso sia comunque inferiore ad un dato valore, diverso da sezione a sezione. Infatti le sezioni più prossimali avranno sempre un’attivazione minore di quelle più distali e l’attivazione crescerà in modo proporzionale alla distanza dalla base come individuato con gli esperimenti del primo set up. Il terzo comando if indica che se il valore di setPoint è compreso tra il limite alto e quello basso allora si aumenta la sua grandezza proporzionalmente a j.

Tale controllo è stato creato ispirandosi ad una serie di rette, che rappresentano l’attivazione di ogni motore collegato ai gruppi di longi-trasversali. Le rette visibili in Fig.5.5 sono parallele, ma sfasate nel tempo, in modo che i motori partano in sequenza.

Fig.4.5 schema esplicativo delle attivazioni dei gruppi di cavi longi-trasversali. L’attivazione che comincia al tempo minore si riferisce al primo gruppo di longi-trasversali, l’attivazione seguente si riferisce al secondo gruppo di longi-trasversali e così a seguire

(23)

73

Il controllo è fatto in modo che si abbia prima la retroflessione, poi si rilascino i due motori che governano i cavi longitudinali e contemporaneamente cominci la contrazione sequenziale dei longi-trasversali.

Questo tipo di controllo è molto adatto ad implementare più facilmente il “recupero” di cavo nelle attivazioni dei gruppi longi-trasversali, ma non ha la possibilità di essere modificato in tempo reale come l’altro quindi risulta meno adatto alla realizzazione di esperimenti ripetuti.

Figura

Tab. 4.1 Corrispondenza tra cavi e motori. I riferimenti relativi ai longitudinali si  riferiscono ad una vista del mock-up dalla parte della base
Fig. 4.1 tempistiche e dinamica del movimento di reaching nel polpo
Tab. 4.2 attivazione per i servo motori collegati ai gruppi di strizione trasversali  utilizzati
Fig. 4.2 Immagine dimostrativa presa da uno dei video  realizzati
+5

Riferimenti

Documenti correlati

0438.1710109 info@d-recta.it - www.d-recta.it Società con Sistema Qualità Certificato secondo UNI EN ISO 9001:2008.. GRUPPO INTERDISCIPLINARE

La misurazione delle forze di reazione del terreno durante la corsa degli scarafaggi, ha dimostrato che le loro zampe agiscono principalmente come elementi di propulsione e che la

They are a set of functions that calculate the necessary and su¢ cient share of the total vote to win a given number of seats that are particularly distributed among all

Obradovic, Daniela 2007, ‘Interest groups and new forms of democracy’, presentation to be convey at the ‘Round table: EU Legitimacy at the National Level’, organised by

Questi ultimi vengono descritti come «interpretazioni generali o applicative di norme organizzative, di programmazione finanziaria, di previsione, di gestione, di

Belki kasabada gerçek hayat bulabilir, ve burada bağlantılar bile daha samimidirler: büyük bir şehirde her şey yanlış, ve insanlarda hiçbir şey için zaman yok, ve anakent

R3 elevato (sono possibili problemi per l’incolumità delle persone, danni funzionali agli edifici ed alle infrastrutture con conseguente inagibilità degli stessi, l’interruzione di

îï ðñKòBóGô õ5ö÷;ñ—ø óIôDòúùDôDò5÷;ñ—öfùDùBö=ûYóWûYüyðñfýQþNóWïIù ô òf÷/ñ{ÿ"óWýUýQþ;÷YûYó„ðñyûó„ÿùBþ÷÷/ñyöKïWï -öKÿÿþOûþöKïWþOþNóWï:ýUñøô ïWñ{øóIôDò