Tutorial · Intermedio · 35 min
Macchina a stati per prelievo, posizionamento e guasti
Avvicinati, afferra, verifica, solleva e posa in una macchina a stati. Il passaggio di verifica rende il robot affidabile anche senza supervisione.
Perché la dimostrazione funziona e il sistema no
Il primo ciclo di prelievo e posizionamento di chiunque è un elenco di chiamate a delay(). Muoviti qui, chiudi la pinza, muoviti lì, aprila. Funziona in un video e funziona circa ottanta volte su cento sul banco di prova, il che sembra abbastanza vicino al completamento.
Non lo è, perché le venti ripetizioni fallite sono tutte silenziose. La pinza si è chiusa sul nulla e il braccio ha trasportato aria sopra il tavolo, poi ha aperto sopra il contenitore. Il componente era leggermente inclinato ed è stato rovesciato invece di essere afferrato. L’alimentatore del servomotore è andato in brown-out durante il sollevamento e il controllore si è riavviato in una posa sconosciuta con le mascelle chiuse.
A trasformare questi disastri in recuperi basta una cosa: un passo di verifica fra la presa e il sollevamento, e una macchina a stati che sa dove andare quando fallisce. Questo è l’intero argomento della pagina.
Gli stati
Un ciclo di prelievo e posizionamento è composto da nove stati; vale la pena nominarli tutti invece di accorparli.
| Stato | Che cosa accade | Condizione di uscita |
|---|---|---|
IDLE |
In attesa di un lavoro | Arriva una richiesta di presa |
APPROACH |
Movimento verso una posa sopra l’oggetto, pinza aperta | Il braccio si è stabilizzato |
DESCEND |
Movimento in linea retta verso la posa di presa | Raggiunta la profondità, oppure scatta un sensore di contatto |
GRASP |
Chiude le mascelle, poi rimane in attesa | Trascorso il tempo di attesa |
VERIFY |
Controlla che sia davvero trattenuto qualcosa | Trattenuto → LIFT. Vuoto → RECOVER |
LIFT |
Movimento in linea retta fino alla posa di avvicinamento | Il braccio si è stabilizzato |
TRANSFER |
Movimento sopra il bersaglio di posizionamento | Il braccio si è stabilizzato |
PLACE |
Scende, apre, attende e si ritira | Retromarcia completata |
RECOVER |
Riapre, si ritira, conta il tentativo e prova ancora oppure si arrende | Nuovo tentativo → APPROACH. Abbandono → IDLE con un guasto |
Due aspetti progettuali svolgono gran parte del lavoro.
Le pose di avvicinamento e retromarcia sono stati separati, sopra l’oggetto. Una pinza che si getta direttamente sul componente da una direzione arbitraria lo rovescia; una pinza che solleva lungo una curva trascina il componente di lato prima che si liberi. Avvicinati sempre dall’alto in verticale, oppure direttamente lungo l’asse di inserimento, con un breve tratto rettilineo, e ripeti lo stesso procedimento per uscire.
VERIFY è uno stato, non una riga di codice. È l’unico punto del ciclo in cui la macchina scopre se la realtà corrisponde al piano, e deve avere un ramo in cui fallire.
Verifica della presa
Quattro metodi, dal più economico in poi. Usane almeno uno.
Controllo della posizione delle mascelle (gratuito)
Se la pinza ha un minimo di cedevolezza in serie, una presa su un oggetto ferma le mascelle prima della posizione raggiunta chiudendole sull’aria. Se puoi leggere la posizione delle mascelle, confrontarla con quella di chiusura sull’aria ti dice che qualcosa si trova fra le dita.
Con un semplice servomotore hobbistico non puoi leggere la posizione, perché funziona in anello aperto. Ma se porti il cursore del potenziometro su un pin ADC, ottieni questa funzionalità al prezzo di un filo e la modifica richiede dieci minuti.
Limiti: indica che c’è qualcosa, ma non che sia l’oggetto giusto né che sia trattenuto bene.
Un microswitch sul dito (circa 50p)
Un microswitch a leva sulla faccia interna di un dito, collegato a un pin di ingresso con resistenza di pull-up. Si chiude quando il contatto tocca qualcosa.
Questa è l’opzione con il miglior rapporto valore-prezzo in assoluto. Fornisce una risposta digitale diretta alla domanda «c’è qualcosa fra le mascelle?», resiste a tutto e si filtra via software in tre righe. Mettilo sulla parte cedevole del dito, così scatta in modo affidabile a una forza riproducibile.
Rilevamento della corrente (circa £2)
Una resistenza di misura (shunt) o un sensore di Hall sull’alimentatore del servomotore. Un servomotore che chiude sull’aria scende alla corrente minima; uno che chiude su un oggetto mantiene una corrente elevata.
Limiti: è rumoroso, richiede una soglia calibrata e sbaglia quando la batteria si scarica. Vale la pena se vuoi rilevare anche uno schiacciamento, non soltanto una presa: una corrente molto superiore al valore previsto significa che il componente è più duro del previsto oppure che hai mancato il bersaglio e afferrato il supporto.
Interruzione del fascio fra le mascelle (circa £1)
Un emettitore IR e un fototransistore attraverso l’apertura delle mascelle. Un fascio interrotto indica che qualcosa occupa lo spazio.
Limiti: vede l’oggetto prima che tu lo abbia afferrato, quindi verifica la presenza anziché la presa. Abbinalo a un altro metodo. È davvero valido su macchine che prelevano oggetti trasparenti o scuri, dove la visione incontra difficoltà.
Scrivere il codice
Il modello è una normale macchina a stati finiti con un timer non bloccante, così nulla nel ciclo si blocca e l’arresto di emergenza resta reattivo:
enum State { IDLE, APPROACH, DESCEND, GRASP, VERIFY, LIFT, TRANSFER, PLACE, RECOVER };
State state = IDLE;
uint32_t stateEnteredAt = 0;
uint8_t attempts = 0;
const uint8_t MAX_ATTEMPTS = 3;
const uint16_t GRASP_DWELL_MS = 350; // let the compliance settle before you trust it
const uint16_t SETTLE_MS = 250;
void enter(State next) { state = next; stateEnteredAt = millis(); }
bool elapsed(uint16_t ms) { return millis() - stateEnteredAt >= ms; }
// Debounced: one reading is a glitch, three in a row is a fact.
bool objectHeld() {
static uint8_t streak = 0;
streak = digitalRead(GRIP_SWITCH) == LOW ? min(streak + 1, 3) : 0;
return streak >= 3;
}
void loop() {
arm.update(); // non-blocking motion, every pass
gripper.update();
switch (state) {
case IDLE:
if (jobPending()) { attempts = 0; arm.moveTo(approachPose); enter(APPROACH); }
break;
case APPROACH:
gripper.open();
if (arm.arrived() && elapsed(SETTLE_MS)) { arm.moveTo(graspPose); enter(DESCEND); }
break;
case DESCEND:
if (arm.arrived()) { gripper.close(); enter(GRASP); }
break;
case GRASP:
// The dwell is not politeness. A compliant finger rings after closing,
// and reading the switch during the ring gives you a coin flip.
if (elapsed(GRASP_DWELL_MS)) enter(VERIFY);
break;
case VERIFY:
if (objectHeld()) { arm.moveTo(approachPose); enter(LIFT); }
else { enter(RECOVER); }
break;
case LIFT:
if (arm.arrived()) { arm.moveTo(placeApproach); enter(TRANSFER); }
break;
case TRANSFER:
if (arm.arrived()) { arm.moveTo(placePose); enter(PLACE); }
break;
case PLACE:
if (arm.arrived() && elapsed(SETTLE_MS)) {
gripper.open();
// Open BEFORE retreating, and retreat straight up, or you drag the part.
if (elapsed(SETTLE_MS + 200)) { arm.moveTo(placeApproach); enter(IDLE); }
}
break;
case RECOVER:
gripper.open();
if (elapsed(SETTLE_MS)) {
if (++attempts < MAX_ATTEMPTS) { arm.moveTo(approachPose); enter(APPROACH); }
else { raiseFault("grasp failed after 3 attempts"); enter(IDLE); }
}
break;
}
}
Tre dettagli in questo codice si guadagnano il loro posto:
L’attesa dopo la presa. Un dito cedevole vibra per un paio di centinaia di millisecondi dopo la chiusura. Se verifichi durante la vibrazione, ottieni una decisione casuale. 300–400 ms di solito bastano; misura il tuo valore registrando lo stato dell’interruttore per un secondo dopo la chiusura.
Verifica filtrata. Una singola lettura dell’interruttore è un disturbo. Tre letture consecutive sono un fatto, e costano tre passaggi di un ciclo che funziona a centinaia di hertz.
Numero limitato di tentativi. Riprovare all’infinito è il modo in cui un robot passa la notte a strofinare contro un componente caduto a terra un’ora prima. Tre tentativi, poi un guasto che deve eliminare una persona.
Che cosa fare quando un nuovo tentativo non basta
RECOVER, così come scritto, prova semplicemente di nuovo dalla stessa posa, il che risolve il caso comune: il componente era leggermente spostato, le mascelle lo hanno urtato e il secondo tentativo va a buon fine. Non risolve un componente che si trova altrove. Ecco alcune escalation utili, in ordine:
- Sposta leggermente l’avvicinamento. A ogni tentativo, sfalsa la posa di presa di qualche millimetro lungo una piccola spirale. Costa tre righe e recupera una frazione sorprendente dei tentativi.
- Rileva di nuovo. Se disponi di una camera o di un sensore di distanza, esegui una nuova misura invece di fidarti della posa fornita.
- Allarga l’apertura. Un’apertura dimensionata esattamente sul componente nominale fallisce quando il componente è ruotato. Al tentativo successivo apri di più.
- Abbandona rumorosamente. Un guasto che ferma la macchina e indica lo stato in cui si trovava è preferibile a una macchina che continua e riempie in silenzio il contenitore degli scarti.
Guasti di cui la pinza non è responsabile
Quando un sistema di prelievo e posizionamento è inaffidabile, spesso la causa non è la presa:
| Sintomo | Causa abituale |
|---|---|
| Fallisce soltanto nei cicli rapidi | Tempo di stabilizzazione insufficiente. Il braccio è arrivato secondo il proprio criterio, ma vibra ancora |
| Fallisce dopo venti minuti | Riscaldamento del servomotore. Vedi la corrente di stallo: le mascelle sono probabilmente rimaste chiuse per tutta la durata |
| Rovescisce il componente in avvicinamento | Scende in diagonale anziché rettilineamente lungo l’asse di inserimento |
| Lo lascia cadere durante il trasferimento, non durante la presa | Accelerazione. La presa è stata dimensionata per una tenuta statica e il movimento ne richiede di più |
| Trascina il componente durante il rilascio | Si ritira prima che le mascelle siano completamente aperte oppure si ritira lungo una curva |
| Il controllore si riavvia durante il ciclo | Brown-out dell’alimentatore del servomotore. Separa la linea di alimentazione del servomotore |
| Funziona, poi smette gradualmente di funzionare | Contatti sporchi. La μ diminuisce con l’accumulo di polvere e non esiste alcun allarme |
La quarta riga merita attenzione, perché è quella che sembra più un mistero. Una presa che sul banco di prova tiene perfettamente può mollare 40 ms dopo l’inizio del sollevamento—prima che il braccio si sia spostato in modo visibile—perché domina il termine di accelerazione. Il simulatore della pinza ti mostra l’istante esatto per i tuoi valori, e la correzione di solito consiste nel rallentare il profilo anziché stringere di più.
Come proseguire
Una volta che il ciclo è affidabile, le aggiunte successive più utili, in ordine di valore, sono:
- Conteggio dei cicli e registro dei guasti. Non puoi migliorare un dato di affidabilità che non misuri.
- Un adeguato profilo di movimento per il trasferimento, così l’accelerazione è limitata e smetti di sovradimensionare la presa per sopravvivere a movimenti bruschi.
- La posa ottenuta dai sensori, non da costanti: è il passaggio dalla dimostrazione alla macchina.
Prossimo passo
- Macchine a stati finiti per il comportamento del robot — il modello generale di cui questo è un’istanza
- Forza, stallo e cedevolezza della pinza servo — perché esiste l’attesa e perché le mascelle non devono restare chiuse
- Tipi di pinza robotica e forza di presa — come dimensionare la presa da cui dipende la sequenza
- Il simulatore della pinza — individua con i tuoi valori l’istante in cui la presa molla
Esplora il grafo
Fa parte di queste costruzioni
Progetti e percorsi di apprendimento che includono questo tutorial.
Per approfondire