UNIVERSITÀ DEGLI STUDI DI NAPOLI “ FEDERICO II ” Facoltà di Ingegneria Dipartimento di Informatica e Sistemistica Corso di Laurea in Ingegneria Informatica Tesi di Laurea In Ingegneria e Tecnologia dei Sistemi di Controllo CONTROLLO “PC‐BASED” DI UNA CELLA ROBOTIZZATA Relatore: Ch.mo Prof. PASQUALE CHIACCHIO Candidato: PASQUALE DI LORENZO Matr. 41/2253 ANNO ACCADEMICO 2003/2004 Ringraziamenti Desidero ringraziare il Prof. Pasquale Chiacchio per avermi dato l’opportunità di concludere il mio corso di studi nel migliore dei modi. L’Ing. Nello Grimaldi per i suoi preziosi consigli e la sua disponibilità a chiarimenti in merito al mondo Real‐Time e non solo. La mia famiglia per il sostegno, la comprensione e l’amore che mi hanno dato e che sempre mi accompagneranno. I miei amici per aver cenato con me alla tavola della vita. “La migliore simulazione è la realtà.” P.D.L. Ai miei nonni I ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Indice Indice Introduzione............................................................................................... 5 CAPITOLO 1 : La Cella Robotizzata ..................................................... 8 1.1 Descrizione del Sistema C3G9000/ROBOT Comau SMART 3S.............. 9 1.1.1 Generalità dei robot Comau SMART 3S..................................................... 9 1.1.2 Generalità del sistema di controllo C3G‐9000 ......................................... 13 1.2 Descrizione degli Organi di Presa Pneumatici ......................................... 19 1.2.1 Mani pneumatiche ....................................................................................... 19 1.2.2 Sensori magnetici ......................................................................................... 21 1.2.3 Elettrovalvole................................................................................................ 21 1.2.4 Compressore, gruppo trattamento aria, sensore di minima pressione 22 1.2.5 Circuito pneumatico per l’azionamento delle mani ............................... 24 1.3 Descrizione del Nastro Trasportatore ......................................................... 25 1.4 Descrizione della Scheda SMARTLAB ...................................................... 28 1.5 Cablaggio della Cella ..................................................................................... 32 1.6 Immagini Fotografiche.................................................................................. 33 CAPITOLO 2 : Architetture di Controllo Real‐Time ....................... 38 2.1 Introduzione al Real‐Time ............................................................................ 39 2.1.1 Hard real‐time e soft real‐time................................................................... 40 2.2 Processi, Thread e Task Real‐Time ............................................................. 42 2.3 Linux Scheduling............................................................................................ 45 2.4 La soluzione RTLinux .................................................................................... 46 2.5 Linux‐RTAI ...................................................................................................... 51 2.5.1 L’Architettura del sistema: RTHAL .......................................................... 51 2.5.2 Implementazione dei servizi e dei processi Real‐Time .......................... 53 2.5.3 RTAI Scheduling .......................................................................................... 53 2.5.4 Hard e Soft Preemption............................................................................... 54 2.5.5 Fondamenti di programmazione real‐time in ambiente RTAI ............. 57 2.6 Un esempio concreto: REPLICS .................................................................. 58 ______________________________________________________________________ II ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Indice CAPITOLO 3 : SOPLICS ...................................................................... 61 3.1. Introduzione .................................................................................................... 62 3.2. Architettura ...................................................................................................... 62 3.3. Parte Real‐Time ............................................................................................... 64 3.3.1 Modulo Principale ....................................................................................... 64 3.3.2 Modulo Device Driver Robot ..................................................................... 70 3.3.3 Modulo Device Driver Smartlab................................................................ 73 3.3.4 Modulo Utente ............................................................................................. 75 3.3.5 Macro e Funzioni ......................................................................................... 77 3.4. Parte Non‐RealTime ....................................................................................... 86 3.4.1 Descrizione dell’Interfaccia Grafica .......................................................... 86 3.5. Compilazione ed Esecuzione di Soplics..................................................... 92 3.6. Un esempio di modulo utente ...................................................................... 93 CAPITOLO 4 : Algoritmi di Controllo della Cella........................... 97 4.1 Specifiche Funzionali del Compito............................................................. 98 4.2 Analisi del modulo utente di controllo .................................................... 101 4.3 Decomposizione funzionale in SFC.......................................................... 105 4.3.1 Ciclo di Pallettizzazione/Depallettizzazione ......................................... 106 4.3.2 Gestione Allarmi ........................................................................................ 129 Bibliografia............................................................................................. 147 Appendice A : Programmi Ausiliari.................................................. 148 Appendice B : Codice sorgente del modulo utente pal_del ......... 150 ______________________________________________________________________ Elenco delle figure III ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Elenco delle Figure Figura 1.1 ‐ Schema in 3D del Robot SMART 3S ..................................................... 10 Figura 1.2 ‐ Struttura del Robot SMART 3S ............................................................. 11 Figura 1.3 ‐ Falange per attacco attrezzi ................................................................... 13 Figura 1.4 ‐ Gerarchia di cella .................................................................................... 14 Figura 1.5 ‐ CRT, tastiera e pannello operatore ....................................................... 15 Figura 1.6 ‐ Terminale di programmazione ............................................................. 16 Figura 1.7 ‐ Corpo centrale della mano..................................................................... 19 Figura 1.8 ‐ Adattatore per la falange attacco attrezzi del robot........................... 20 Figura 1.9 ‐ Dito della mano pneumatica ................................................................. 20 Figura 1.10 ‐ Schema Fotocellula ............................................................................... 27 Figura 1.11 ‐ Schema della scheda Smartlab ............................................................ 29 Figura 1.12 ‐ Posizione switch per l’I/O Address 3E0H ......................................... 31 Figura 1.13 ‐ A sinistra il robot a 6 assi , a destra quello a 7 assi........................... 33 Figura 1.14 ‐ Unità di controllo C3G‐9000................................................................ 33 Figura 1.15 ‐ Pannello operatore ................................................................................ 33 Figura 1.16 ‐ Pinza pneumatica.................................................................................. 34 Figura 1.17 ‐ Particolare dellʹattacco falange............................................................ 34 Figura 1.18 ‐ Compressore .......................................................................................... 34 Figura 1.19 ‐ Lubrificatore .......................................................................................... 34 Figura 1.20 ‐ Sensore per la pressione....................................................................... 34 Figura 1.21 ‐ Pannello di controllo del Nastro......................................................... 34 Figura 1.22 ‐ La scheda SMARTLAB......................................................................... 35 Figura 1.23 ‐ Dispositivo di Interfacciamento per la scheda Smartlab................. 35 Figura 1.24 ‐ Robot a 6 assi in fase di prelievo pezzo dal vassoio di sinistra ...... 36 Figura 1.25 ‐ Robot a 6 assi in fase di deposito pezzo sul nastro .......................... 36 Figura 1.26 ‐ Robot a 7 assi in fase di deposito pezzo sul vassoio di destra........ 37 Figura 1.27 ‐ Disposizione dei pezzi a fine pallettizzazione.................................. 37 Figura 2.28 ‐ Architettura RTAI ................................................................................. 51 Figura 2.29 ‐ Set‐Up Replics........................................................................................ 59 Figura 2.30 ‐ Interfaccia grafica di Replics ............................................................... 60 Figura 3.31 ‐ Replics : Vista 3D dei robot Smart 3S ................................................. 60 Figura 3.32 ‐ Architettura di Soplics.......................................................................... 63 Figura 3.33 ‐ Struttura del Modulo Principale ......................................................... 65 Figura 3.34 ‐ Struttura del modulo driver per i robot............................................. 70 Figura 3.35 ‐ Struttura del modulo driver per la scheda Smartlab ....................... 73 Figura 3.36 ‐ Schema per la scrittura di un modulo utente.................................... 75 ______________________________________________________________________ Elenco delle figure IV ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Figura 3.37 ‐ Soplics : Configurazione ...................................................................... 87 Figura 3.38 ‐ Soplics : Scelta dei dispositivi.............................................................. 88 Figura 3.39 ‐ Soplics : Quadro Sinottico.................................................................... 89 Figura 3.40 ‐ Soplics : Monitor per la visualizzazione dei messaggi .................... 91 Figura 3.41 ‐ SFC esempio modulo utente ............................................................... 94 Figura 4.42 ‐ Pezzi di plastica usati nella movimentazione ................................... 98 Figura 4.43 ‐ SFC funzionale: GR1‐ Generale......................................................... 107 Figura 4.44 ‐ SFC operativo: GR1 ‐ Generale ......................................................... 108 Figura 4.45 ‐ SFC funzionale : GR2 Nastro............................................................. 109 Figura 4.46 ‐ SFC operativo : GR2 Nastro............................................................... 110 Figura 4.47 ‐ SFC funzionale : GR3 Robot_6A ....................................................... 111 Figura 4.48 ‐ SFC operativo : GR3 Robot_6A ......................................................... 111 Figura 4.49 ‐ SFC funzionale : macrofase M3.1 Pallettizzazione‐Robot6A........ 113 Figura 4.50 ‐ SFC operativo : macrofase M3.1 Palletttizzazione‐Robot6A ........ 115 Figura 4.51 ‐ SFC funzionale : macrofase M3.2 Depallettizzazione Robot6A ... 117 Figura 4.52 ‐ SFC operativo : macrofase M3.2 Depallettizzazione Robot6A..... 119 Figura 4.53 ‐ SFC funzionale: GR4 Robot_7A ........................................................ 120 Figura 4.54 ‐ SFC operativo: GR4 Robot_7A .......................................................... 120 Figura 4.55 ‐ SFC funzionale: macrofase M4.1 Pallettizzazione‐Robot7A......... 122 Figura 4.56 ‐ SFC operativo: macrofase M4.1 Pallettizzazione Robot7A........... 124 Figura 4.57 ‐ SFC funzionale: macrofase M4.2 Depallettizzazione Robot7A .... 126 Figura 4.58 ‐ SFC operativo: macrofase M4.2 Depallettizzazione Robot7A...... 128 Figura 4.59 ‐ SFC funzionale: GRA1 ‐Malfunzionamento Fotocellule ............... 130 Figura 4.60 ‐ SFC operativo: GRA1 ‐Malfunzionamento Fotocellule................. 131 Figura 4.61 ‐ SFC funzionale: GRA2 Allarme Pinza 0 .......................................... 132 Figura 4.62 ‐ SFC operativo: GRA2 Allarme Pinza 0 ............................................ 133 Figura 4.63 ‐ SFC funzionale: GRA3 Allarme Pinza 1 .......................................... 134 Figura 4.64 ‐ SFC operativo: GRA3 Allarme Pinza 1 ............................................ 135 Figura 4.65 ‐ SFC funzionale: GRA4 Allarme Sovraccarico Termico ................. 137 Figura 4.66 ‐ SFC operativo: GRA4 Allarme Sovraccarico Termico ................... 138 Figura 4.67 ‐ SFC funzionale: GRA5 Allarme Compressore................................ 139 Figura 4.68 ‐ SFC operativo: GRA5 Allarme Compressore.................................. 139 Figura 4.69 ‐ SFC funzionale: GRA6 Allarme riconoscimento pezzo................. 141 Figura 4.70 ‐ SFC operativo: GRA6 Allarme riconoscimento pezzo .................. 141 Figura 4.71 ‐ SFC funzionale: GRA7 Allarme Robot_6A...................................... 143 Figura 4.72 ‐ SFC operativo: GRA7 Allarme Robot_6A ....................................... 144 Figura 4.73 ‐ SFC funzionale: GRA8 Allarme Robot_7A...................................... 145 Figura 4.74 ‐ SFC operativo: GRA8 Allarme Robot_7A ....................................... 146 ______________________________________________________________________ Introduzione 5 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Introduzione PBC (PLC‐PC Based Control) è una sigla che sempre più spesso si sente nel mondo dellʹautomazione industriale. Il controllo ʺPC‐Basedʺ attira sempre più attenzioni perché il binomio Alte Prestazioni‐Basso costo è e lo sarà sempre, lʹobiettivo principale da raggiungere. Quello che però frenava lo sviluppo in tale direzione era che tutta questa potenza di calcolo, che i moderni Personal Computer offrono, se non è affiancata da altre caratteristiche quali affidabilità, sicurezza e soprattutto determinismo, non è di nessuna utilità. Infatti non è possibile affidare il controllo di un processo industriale ad un Sistema Operativo che allʹimprovviso potrebbe rivolgere la propria attenzione ad un altro processo, che fosse pure una systemcall, e lasciare al proprio destino un pezzo su di una catena di montaggio. Da un po’ di tempo le cose sono cambiate, perché sono stati sviluppati Sistemi Operativi Real‐Time, ossia SO che mettono al primo posto la gestione dei processi in tempo reale. Un valido esempio in tal senso è LINUX‐RTAI, che offre la gestione di processi real‐time permettendo allo stesso tempo di usufruire di tutti quei servizi tipici di un moderno Sistema Operativo. Il lavoro di tesi, ha riguardato proprio lo sviluppo di un software, denominato SOPLICS (SOftware Plc under LInux Control System) per il controllo e la supervisione di una cella robotizzata, utilizzando tale sistema operativo. ______________________________________________________________________ Introduzione 6 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ La cella robotizzata è situata presso il laboratorio PRISMA del dipartimento di Informatica e Sistemistica dellʹUniversità di Napoli Federico II, e comprende le seguenti apparecchiature: due bracci robotici Smart 3S con le relative unità di governo C3G‐9000, due mani pneumatiche con il relativo circuito per il funzionamento, e un nastro trasportatore. Lʹunità di controllo dellʹintero sistema è costituito da un PC dotato di un processore di classe Pentium con sopra installato il sistema operativo Linux‐RTAI e con allʹinterno alloggiate le schede di comunicazione per il controllo dei robot e la scheda per lʹI/O dei segnali digitali per il nastro e le pinze. Soplics ha una struttura modulare, tipica degli ultimi Kernel di Linux, e questo rende il sistema facilmente espansibile e personalizzabile secondo i servizi richiesti. Eʹ costituito dai due moduli device‐driver, uno per la comunicazione con i robot e l’altro per la comunicazione pinze/nastro, e dal modulo principale che si occupa dellʹesecuzione del ciclo di controllo della cella. Il meccanismo per il controllo è ripreso da quello del PLC (Programmable Logic Controller) industriale, ossia: lettura degli ingressi, scansione dell’algoritmo di controllo, aggiornamento delle uscite; questo approccio permette una relativa semplicità implementativa e offre unʹottima robustezza strutturale. In più è prevista la gestione di eventi asincroni (massimo tre) al ciclo di controllo, al verificarsi dei quali si può decidere di far eseguire un qualsivoglia compito generale . In realtà Soplics è un ambiente di controllo per la cella un pó più generale, in quanto è possibile far girare un generico modulo di controllo scritto da un utente. Tale modulo, a grandi linee, non è altro che la traduzione in linguaggio C di un SFC (Sequential Functional Chart) di controllo, che è uno dei linguaggi tipici dei PLC. Ciò non risulta affatto complesso, infatti la logica usata in un SFC è di tipo sequenziale guidata da eventi , ossia se è verificata una certa ______________________________________________________________________ Introduzione 7 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ condizione allora esegui un’azione, e questo si traduce semplicemente in una serie di IF‐THEN. Naturalmente questa è una notevole semplificazione ma dà bene l’idea della semplicità che sta alla base di un sistema di controllo. Tutto questo ha permesso di unire la potenza rappresentativa di un algoritmo scritto utilizzando lʹSFC con la potenza e la praticità di un linguaggio di programmazione come il C. Nel Capitolo 1 saranno descritte le caratteristiche sia fisiche che funzionali dei singoli componenti della cella, e il cablaggio ex‐novo che è stato effettuato per il collegamento dei segnali di controllo delle pinze e del nastro trasportatore. Nel Capitolo 2 si parlerà delle architetture Real‐Time, con particolare attenzione, naturalmente al Sistema Operativo usato per lo sviluppo del software, ossia Linux‐RTAI. Nel Capitolo 3 si analizzerà dettagliatamente il software implementato (SOPLICS), sia da un punto di vista architetturale che funzionale. Inoltre verrà descritta l’interfaccia grafica che funge da sistema di supervisione per la cella robotizzata. Nel Capitolo 4 infine sarà descritta l’implementazione di un modulo utente per il controllo completo della cella, compresi i segnali di allarme, che realizza un ciclo di Pallettizzazione/Depallettizzazione. ______________________________________________________________________ Capitolo 1: La Cella Robotizzata 8 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ _______________________________________________ CAPITOLO 1 : La Cella Robotizzata _______________________________________________ Nel seguente capitolo si parlerà dell’architettura della cella robotizza presente nel laboratorio PRISMA del dipartimento di Informatica e Sistemistica dell’Università di Napoli, descrivendo sia le caratteristiche fisiche che funzionali dei singoli componenti. ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – C3G9000/Robot SMART 3S 9 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 1.1 Descrizione del Sistema C3G9000/ROBOT Comau SMART 3S 1.1.1 Generalità dei robot Comau SMART 3S In laboratorio sono presenti due robot COMAU Smart 3S di tipo antropomorfo a sei gradi di liberta con relative unità di governo C3G‐9000 (descritta nel paragrafo successivo) e moduli d’interfaccia per la rete RIO. Uno dei due robot è montato su una slitta attuata con una corsa di 2 metri che ne estende lo spazio di lavoro portando a sette i gradi di libertà. Lo SMART 3S è un robot adatto per applicazioni del tipo: • saldatura ad arco • manipolazione di piccoli oggetti • dispensazione di sigillante • lavorazioni con getto d’acqua La movimentazione degli assi è comandata da motori brushless ed inoltre tutti gli assi sono dotati di freni (che si inseriscono quando i motori non sono alimentati). La capacità di carico è di 6 Kg applicabile a 215mm dal centro polso. Il sistema di misura posizione assi è di tipo assoluto realizzato con un solo revolver integrato nel motore ed un modulo di traduzione assoluta RTP (Revolver Position Tracker) alloggiato nello smistamento inferiore del robot. ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – C3G9000/Robot SMART 3S 10 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Lo sbraccio massimo orizzontale è di 1400mm, lo sbraccio massimo verticale è di 2100mm e la ripetitività di posizione è pari a ± 0.10mm. Sono previsti dei fine corsa software (programmabili) su tutti gli assi, dei fine corsa elettrici opzionali, meccanici e fissi sugli assi 1, 2 e 3. Una bella rappresentazione in 3D del Robot SMART 3S è data dalla figura seguente (fig. 1.1) Figura 1.1 - Schema in 3D del Robot SMART 3S Nella figura 1.2, invece, è possibile vedere una dettagliata schematizzazione della struttura del robot, in cui è possibile distinguere i componenti principali elencati nella successiva tabella(Tab1.1) ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – C3G9000/Robot SMART 3S 11 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Figura 1.2 - Struttura del Robot SMART 3S ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – C3G9000/Robot SMART 3S 12 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Assemblies Structure ASSEMBLY MECHANICAL GRUOUPS REF. FIG. 1 Wrist (Axes 5-6) Axis 6 motor unit Axis 6 reducer unit Axis 5 reducer unit Wrist joint unit Axis 5 motor unit 1 2 3 4 5 Axis 4 reducer unit Axis 4 motor unit Upper distribution 6 7 8 Axis 2 electrical limit stop unit Axis 2 mechanical limit stop unit Axis 2 motor unit Axis 2 reducer unit Axis 3 reducer unit Axis 3 electrical limit stop unit Axis 3 mechanical limit stop unit Axis 3 motor unit 17 NI 9 10 11 18 NI 12 Axis 1 motor unit Axis 1 reducer unit Axis 1 electrical limit stop unit Axis 1 mechanical limit stop unit Lower distribution 13 14 16 NI 15 Forearm (Axis 4) Arm (Axes 2-3) Base (Axis 1) NI: Not illustrated Tabella 1.1 – Componenti principali del robot nella seguente tabella (Tab.1.2),invece, sono riportate la corsa e la velocità degli assi Asse 1 Asse 2 Asse 3 Asse 4 Asse 5 Asse 6 Corsa ±165° +135°, ‐80° ‐75°, +90° ±175° ±140° ±175° Velocità 132°/sec 110°/sec 150°/sec 360°/sec 360°/sec 480°/sec Tabella 1.2 - Caratteristiche di corsa e di velocità degli assi ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – C3G9000/Robot SMART 3S 13 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Infine nella figura seguente è riportata lo schema della falange attrezzi (fig. 1.1) Figura 1.3 - Falange per attacco attrezzi 1.1.2 Generalità del sistema di controllo C3G‐9000 L’unità di governo del robot SMART-3S è il sistema di controllo C3G9000, che è in grado di eseguire diversi processi programmabili dall’utente sia per funzioni logiche sia per l’effettivo controllo del movimento. Un unico sistema di controllo può essere utilizzato per più macchine, inoltre è possibile eseguire più programmi contemporaneamente per gestire tutti gli aspetti di una applicazione. Il sistema controllato dal C3G è strutturato a livelli gerarchici. Al livello più basso vi èl’asse, esso è fisicamente identificato dal motore che ne permette la movimentazione e definisce un grado di libertà del sistema stesso. Il braccio (arm) è costituito da un insieme di assi, da un minimo di 1 ad un massimo di 8, raggruppati logicamenteed il cui moto è coordinato da un unico interpolatore. Il braccio rappresenta il minimo elemento controllabile da programma; uno o due bracci collegati fisicamente o da un punto di vista logico formano una macchina, la quale può gestire fino ad un massimo di otto ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – C3G9000/Robot SMART 3S 14 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ assi. La cella costituisce l’elemento globale composto da una o più macchine, fino ad un massimo di 4. La cella è in grado di gestire da 1 a 32 assi ed è caratterizzata da un unico sistema di controllo che svolge funzioni di gestore degli stati, interfaccia operatore, programmazione, controllo e visualizzazione. In figura 1.4 è mostrata la struttura gerarchica di un sistema controllato C3G. Figura 1.4 - Gerarchia di cella Il controllore C3G è costituito da tre sistemi principali: ¾ Gruppo pannello operatore; ¾ unità di controllo che gestisce le funzioni dell’ interfaccia operatore ed esegue gli algoritmi di controllo del movimento; ¾ unità driver motore, ossia la parte di amplificazione di potenza. Vedremo un po’ più in dettaglio l’interfaccia operatore e l’unità di controllo. ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – C3G9000/Robot SMART 3S 15 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Gruppo pannello operatore Il gruppo pannello operatore rappresenta l’interfaccia del sistema di controllo verso l’operatore. Esso è composto dal pannello operatore, dall’unità CRT/tastiera e dal terminale di programmazione ed è unico all’interno della cella (fig. 1.5). CRT Tastiera Pannello Operatore Sportelli Figura 1.5 - CRT, tastiera e pannello operatore Sul pannello operatore vi è posizionato l’interruttore di alimentazione, il pulsante di arresto d’emergenza, il deviatore per la modalità locale (local), remota (remote) o di programmazione (prog), i comandi di accendi motore (drive on), spegni motore (drive off), avvia programma (start), metti in attesa il programma (hold). I pulsanti di emergenza, drive off e hold funzionano in qualsiasi modalità (prog, local o remote) mentre quelli di drive on e start hanno effetto solo in modalità locale; bisogna notare che anche se si è in modalità ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – C3G9000/Robot SMART 3S 16 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ locale i comandi di drive off e hold remoti e del terminale di programmazione devono essere disabilitati altrimenti il drive on non ha effetto. Figura 1.6 - Terminale di programmazione ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – C3G9000/Robot SMART 3S 17 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unità di controllo L’unità di controllo C3G è basata sul bus Motorola VME e comprende due schede con CPU: • RBC (RoBotCpu): gestisce l’interfaccia uomo‐macchina e traduce ed interpreta i programmi PDL2 propri del controllore. Su questa scheda è presente un’area di memoria, chiamata “shared memory”, alla quale si può accedere da tutte le schede collegate al bus VME, scheda RBC inclusa. • SCC (Servo Control Cpu): È responsabile della programmazione e dell’interpolazione della traiettoria (sia in coordinate di giunto che in quelle cartesiane), della cinematica inversa, della microinterpolazione e del controllo posizione giunto; è dotata anche di un DSP (Digital Signal Processor). Nella attuale versione il controllore standard C3G‐9000 è stato aggiornato per permettere la cosiddetta modalità di controllo “aperta”, cioè è possibile la comunicazione tra il C3G‐9000 ed il PC, interfacciando il bus VME del controllore con il bus ISA di un PC tramite due schede Bit3, collegate tra di loro con un cavo ad alta velocità. Lo scambio di dati avviene nella shared memory della RBC. La sincronizzazione tra il controllore C3G ed il PC si ottiene tramite un segnale di interrupt generato dal controllore C3G con periodo funzione della modalità utilizzata. Nella modalità aperta esistono cinque modi di funzionamento del controllore. Essi si distinguono l’uno dall’altro a seconda del punto in cui viene aperto lo schema di controllo standard del C3G. ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – C3G9000/Robot SMART 3S 18 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ La modalità più utilizzata è caratterizzata da un periodo di campionamento di 1ms. Il controllo del C3G è aperto a valle del loop di posizione e velocità assi: il PC legge le posizioni dei sei giunti e scrive direttamente i setpoint di corrente, con tutti i controlli di sicurezza disabilitati. Ecco perché questa modalità è la più pericolosa ma è anche quella che permette maggiori libertà. Il controllo di un manipolatore consiste nel determinare le coppie e le forze che gli attuatori devono applicare ai giunti, in modo da garantire l’esecuzione dei movimenti desiderati. Si distingue fra controllo nello spazio di giunto e controllo nello spazio operativo. Il primo presenta come vantaggio il minor carico computazionale e presuppone l’inseguimento di traiettorie generate nello spazio di giunto, il controllo sulle grandezze nello spazio operativo avviene quindi in catena aperta. La seconda strategia, pur richiedendo una maggiore complessità algoritmica, presuppone l’inversione cinematica interna all’anello di controllo, quindi le misure vengono fatte direttamente nello spazio operativo. Il software di controllo del robot inizialmente era stato fatto in MS‐ DOS, poi si è passati ad un sistema operativo più potente come RTAI‐Linux1, in particolare è stato creato un ambiente, REPLICS2, con spiccate caratteristiche user‐friendly per il controllo completo dei robot. _________________________________________________________________________________________________________________________ 1 RTAI‐Linux sarà ampiamente trattato nel Capitolo 2, esso infatti costituisce l’ambiente di sviluppo del lavoro di Tesi. REPLICS è un software ideato e realizzato dall’ingegnere Nello Grimaldi, esso sarà descritto nel secondo capitolo Per informazioni più dettagliate si rimanda al manuale completo elencato nella bibliografia. 2 Capitolo 1: La Cella Robotizzata – Organi di Presa Pneumatici 19 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 1.2 Descrizione degli Organi di Presa Pneumatici 1.2.1 Mani pneumatiche La cella robotizzata è stata realizzata installando delle mani pneumatiche, costituite da dita metalliche montate su un pistone pneumatico tipo MCPA40 della MAPOR CALDART, sui due robot. I pistoni sono caratterizzati da una chiusura della ganasce in parallelo, da un alesaggio di 40mm e da una pressione di lavoro che deve essere compresa tra i 2 ed i 7 bar. Il cilindro della mano è a doppio effetto (fig. 1.7); per l’attacco della mano sulla falange attrezzi del robot è stato usato un adattatore mostrato in figura 1.8 mentre in figura 1.9 vi è mostrato lo schema delle dita alle cui estremità vi è uno strato di gomma per migliorarne la presa. Figura 1.7 - Corpo centrale della mano ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Organi di Presa Pneumatici 20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Figura 1.8 - Adattatore per la falange attacco attrezzi del robot Figura 1.9 - Dito della mano pneumatica ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Organi di Presa Pneumatici 21 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 1.2.2 Sensori magnetici Lo stato della mano è controllato mediante dei sensori magnetici del tipo MA1 (MAPOR CALDART). Questi sensori, utilizzati per segnalare il raggiungimento dei fine corsa della mano (segnalano gli stati mano aperta e mano chiusa) sono montati su delle scanalature laterali presenti sul corpo centrale della mano. Il loro funzionamento è dovuto ad un anello magnetizzato che, scorrendo insieme al cilindro del pistone pneumatico, chiude il circuito magnetico, indicando così il raggiungimento del fine corsa relativo. Il raggiungimento del fine corsa viene indicato con l’accensione di un led di colore rosso presente sul sensore. Di seguito sono riportati le caratteristiche tecniche del sensore (tab. 1.3). Sensore Magnetico Voltaggio Potenza massima assorbita Corrente Tempo di risposta Temperatura di esercizio 24 Vcc 1W 5 ÷ 45 mA 1 ms 5 ÷ 60 °C Tabella 1.3 – Caratteristiche tecniche del sensore magnetico per le pinze 1.2.3 Elettrovalvole L’apertura o la chiusura della mano viene comandata con una valvola ad azionamento elettrico. Quella presente in laboratorio è una valvola a cassetto della NORGRENG1/4 – 3 posizioni con utilizzi in scarico nella posizione centrale in modo da poter gestire anche una condizione di stato rilassato. L’azionamento della valvola è dato da due operatori alimentati con una tensione di 24 Vcc, che assorbono una potenza di 8W. Questo tipo di valvola è ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Organi di Presa Pneumatici 22 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ detto doppio azionamento elettropneumatico con ritorno a molla in posizione central. ed è monostabile , finché non viene dato alcun segnale le molle mantengono il cassetto in posizione centrale. Sulle connessioni di scarico dell’elettrovalvola sono montati due regolatori di flusso silenziati; essi hanno la funzione di evitare uno scarico troppo rapido dell’aria presente nella pinza, impedendo così un’apertura violenta della mano. Tali regolatori hanno una pressione massima d’esercizio di 10 bar ed un campo di temperatura pari a 0 ÷ 80 °C. Di seguito sono elencate le caratteristiche tecniche dell’elettrovalvola (tab. 1.4). Elettrovalvola Fluido Pressione max d’sercizio Pressione minima di azionamento Temperatura di funzionamento Temperatura Fluido Sezione minima di passaggio Fissaggi Assorbimento a regime Massima variazione tensione nominale Aria compressa filtrata e lubrificata 10 bar 1.5 bar 0 ÷ 55 °C 0 ÷ 90 °C 50 mm2 N° 2 fori φ 5 mm 8W +10% -15% Tabella 1.4 -Caratteristiche tecniche dell'elettrovalvola 1.2.4 Compressore, gruppo trattamento aria, sensore di minima pressione L’aria compressa, necessaria al funzionamento del circuito pneumatico, è prodotta da un compressore con serbatoio da 25 l che con un motore monofase da 1.5 Hp fornisce aria compressa con pressioni fino ad 8 bar. Quello in uso è un compressore di tipo commerciale che comprende i dispositivi per un controllo elementare del tipo On/Off (sulla pressione del serbatoio), la valvola ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Organi di Presa Pneumatici 23 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ manuale di chiusura, la valvola di sicurezza per la massima pressione del serbatoio, manometro che indica la pressione all’interno del serbatoio e manopola per regolare la pressione di uscita. Il gruppo trattamento aria è composto da un filtro‐regolatore e da un lubrificatore. Il filtro‐regolatore permette un’ulteriore regolazione della pressione di esercizio e contiene un serbatoio di accumulo della condensa. Il lubrificatore inserisce nel circuito dell’aria compressa una quantità di olio proporzionale al consumo d’aria. Nelle due tabelle che seguono vengono elencate le caratteristiche di entrambi. Filtro-regolatore Pressione massima di ingresso Pressione di uscita Temperatura massima di funzionamento Dimensione lineare elemento filtrante 10 bar 0 ÷ 10 bar 50 °C 50 µm Tabella 1.5 - Caratteristiche del filtro-regolatore Lubrificatore Pressione massima di esercizio Campo di funzionamento a 6.3 bar Temperatura massima di funzionamento Capacità serbatoio 10 bar 1 ÷ 10 dm3/s 50 °C 0.05 l Tabella 1.6 - Caratteristiche del lubrificatore Allacciato al gruppo di trattamento aria è posizionato un sensore di minima pressione (pressostato) che indica quando la pressione nel circuito è minore del valore impostato per il buon funzionamento delle mani. Il campo di regolazione è 2 ÷ 6 bar. ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Organi di Presa Pneumatici 24 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 1.2.5 Circuito pneumatico per l’azionamento delle mani Gli elementi descritti nei paragrafi precedenti formano un circuito pneumatico che fornisce aria compresse alle mani. Il primo elemento è il compressore la cui uscita è collegata con il gruppo trattamento aria ( filtro‐regolatore, lubrificatore, sensore di minima pressione ). A valle del gruppo trattamento aria c’è un blocchetto di derivazione (una T) da cui si ripartono due rami che vanno alle due elettrovalvola (una per robot). Le uscite delle elettrovalvola sono collegate al corpo centrale della mano e sulle uscite di scarico sono collegati i regolatori di flusso. Lo schema complessivo del circuito è rappresentato nella figura sottostante (fig. 1.7 ). Tabella 1.7 - Circuito pneumatico 1 2 3 4 5 Compressore Gruppo trattamento aria Elettrovalvola Regolatori di flusso Mani pneumatiche ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Nastro Trasportatore 25 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 1.3 Descrizione del Nastro Trasportatore All’interno della cella automatizzata è presente un nastro trasportatore, della M.I.T.A. Progetti S.r.l, destinato prevalentemente al trasporto di piccoli iggetti in plastica. Sul nastro sono montate quattro fotocellule (Allen‐Bradly) per la rivelazione della presenza del pezzo ed un sensore magnetico (Allen‐Bradly) per la rilevazione del numero di viti inserite nel pezzo che vi transita, mediante il numero di viti, con un’opportuna codifica, è possibile stabilire il colore del pezzo. Il motore del nastro è asincrono trifase e permette lo spostamento del nastro in entrambe le direzioni. Il nastro è stato montato dietro i due robot e fissato in modo permanente ad essi. Inoltre è presente una pulsantiera satellitare, nel pannello di controllo del nastro, per comandare in modalità manuale l’avanzamento del nastro in entrambe le direzioni. Sul pannello di controllo è posto anche il fungo di emergenza, mentre all’interno è presente un interruttore pronto a scattare in caso di sovraccarico termico del motore, interrompendo l’erogazione della corrente. In tab. 1.8 sono elencate le caratteristiche principali del nastro. La parte scorrevole è delimitata da delle spondine per evitare la fuoriuscita dei pezzi. Nella zona centrale sono presenti delle guide per rendere sempre possibile la rilevazione del passaggio della vite presente nel pezzo; mentre agli estremi sono stati fissati due vassoi per il posizionamento dei pezzi di plastica usati per le fasi di pallettizzazione e depallettizzazione. Infine è da segnalare che le regolazioni possibili sono: l’altezza da terra, quanto deve essere teso il nastro e la centratura. ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Nastro Trasportatore 26 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Nastro Trasportatore Serie Tensione elettrica di alimentazione Potenza installata Lunghezza utile Larghezza utile Massa complessiva Livello di pressione sonora Tipo di tela Temperatura max pezzi PNL 1 380 V 0.5 Hp 4000 mm 100 mm 100 Kg < 70 dB PVC 70 °C Tabella 1.8 - Caratteristiche principali del Nastro Le fotocellule per la rilevazione della presenza dei pezzi in una determinata zona del nastro, sono Allen‐Bradly tipo PHOTOSWITCH® Bullettin 42CB High Speed 18 mm Cilindrical. Queste utilizzano un led a luce infrarossa (invisibile)per la rilevazione del pezzo. Sul retro della fotocellula sono montati un potenziometro per la regolazione della distanza di rilevazione, un led di colore verde per indicare che la fotocellula è in funzione ed uno di colore arancione per indicare la presenza del pezzo. Il segnale alto di uscita (24 Vcc) può essere impostato sia per segnalare la presenza che la mancanza dell’oggetto ( light/dark operate ). La frequenza di funzionamento limite è di 1 kHz. Tali dati sono stati riassunti nelle due tabelle che seguono. Fotocellula Protezione da corto circuito; Protezione da inversione di polarità; Potenziometro a singola vite per la regolazione della sensibilità; Due Led indicatori: verde ⇒ alimentazione inserita giallo ⇒ uscita alimentata Due modi di funzionamento – luce/scuro(L.O./D.O.); Tabella 1.9 - Caratteristiche principali delle fotocellule ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Nastro Trasportatore 27 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Fotocellula Umidità relativa, Temperatura ambiente Materiale della lente Peso Tensione di alimentazione Corrente assorbita Massima corrente di carico Campo di funzionamento Angolo visivo Ledi di trasmissione 35 – 85 % -25,+70 °C Acrilico 90 g 10-30 Vcc 20 mA 100 mA 0.08 m – 7.2 m 1.3° Infrared 880 nm Tabella 1.10 - Specifiche della fotocellula Figura 1.10 - Schema Fotocellula Il sensore induttivo è a forma di cilindro filettato di acciaio. La distanza di rilevamento è fissa e dispone di un led di colore rosso per segnalare visivamente la rilevazione della vite nel pezzo. Le altre caratteristiche di funzionamento sono simili a quella della fotocellula (tensione di alimentazione, corrente assorbita, …). ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Scheda SMARTLAB 28 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 1.4 Descrizione della Scheda SMARTLAB Per l’acquisizione e l’invio dei segnali di input e di output per comandare le pinze e il nastro trasportatore si è usata la scheda SMARTLAB 16 CHANNEL Relay/16 Photo Isolator Card. Questa scheda è di tipo ISA, e come si capisce dal nome presenta 16 canali di uscita a relè e 16 canali di ingresso (photo isolator ). L’installazione della scheda all’interno del Computer non ha presentato grossi problemi; prima di inserirla nello slot è bene ricordarsi, però, di settare l’indirizzo base per gli I/O, da decidere tra quelli liberi all’interno della memoria del Sistema Operativo ed, in caso di utilizzo degli interrupt, l’IRQ da utilizzare. Queste due operazione possono essere fatte semplicemente settando gli switch (nel caso I/O) e cortocircuitando i jumper nel caso degli IRQ. Nel nostro coso si è scelto l’indirizzo 3E0H (per il settaggio corrispondente basta consultare il manuale) e si è deciso di non utilizzare gli interrupt, quindi non si è cortocircuitato nessun jumper. Nella figura 1.11 si ha una precisa schematizzazione della scheda in cui si può notare la posizione degli switch per l’ I/O Address ( marcato con SW ) e degli jumper IRQ (JP2 ). ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Scheda SMARTLAB 29 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Figura 1.11 - Schema della scheda Smartlab ____________________________________________________________________________________________________________________ Capitolo 1: La Cella Robotizzata – Scheda SMARTLAB 30 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Output Gli output vengono scritti con una word tramite funzioni del driver. Quando si setta il corrispondente bit ad 1, questo fa accendere il relè ossia esso assume lo stato chiuso, quando invece si setta il corrispondente bit a 0, questo fa spegnere il relè ossia assume lo stato aperto. Photo couple input Gli ingressi funzionano in modo inverso rispetto agli output. Quando in ingresso vi è una tensione compresa tra 0 e 2 VDC, allora il circuito di ingresso si spegne e il corrispondente bit sarà settato a 0, mentre se la tensione di ingresso è compresa tra 3 e 45 VDC , allora il circuito si accende e il corrispondente bit sarà settato ad 1. La massima tensione supportata è di 50 VDC. Di seguito sono mostrate le caratteristiche salienti della scheda, l’assegnazione dei PIN di ingresso e di uscita, e il settaggio usato per l’ I/O address (Tab. 1.11 , 1.12 ; Fig. 1.12 ). Smartlab 16 CHANNEL Relay/16 Photo Isolator Card Features : Support 16 relay output channels and 16 photo couple input channels Max contact rating for relay: 150V / DC 1AMP. Response time for relay: 1 ms minimum. Contact resistance for relay: 0.2-OHM maximum. Support several operating modes which are Programmable Sixteen LED indicate when I/O is operating. Port address selectable. Tabella 1.11 - Caratteristiche della scheda SMARTLAB ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Scheda SMARTLAB 31 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ PIN OUTPUT INPUT 1, 2 3, 4 5, 6 7, 8 9, 10 11, 12 13, 14 15, 16 17, 18 19, 20 21, 22 23, 24 25, 26 27, 28 29, 30 31, 32 33, 34 35, 36 37, 38 39, 40 Relay channel 1 Relay channel 2 Relay channel 3 Relay channel 4 Relay channel 5 Relay channel 6 Relay channel 7 Relay channel 8 Relay channel 9 Relay channel 10 Relay channel 11 Relay channel 12 Relay channel 13 Relay channel 14 Relay channel 15 Relay channel 16 GND DC +5 V DC +12 V GND Input channel 1- , 1+ Input channel 2- , 2+ Input channel 3- , 3+ Input channel 4- , 4+ Input channel 5- , 5+ Input channel 6- , 6+ Input channel 7- , 7+ Input channel 8- , 8+ Input channel 9- , 9+ Input channel 10- , 10+ Input channel 11- , 11+ Input channel 12- , 12+ Input channel 13- , 13+ Input channel 14- , 14+ Input channel 15- , 15+ Input channel 16- , 16+ GND DC +5 V DC +12 V GND Tabella 1.12 - Assegnazione dei Pin della scheda Smartlab Figura 1.12 - Posizione switch per l’I/O Address 3E0H ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Cablaggio 32 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 1.5 Cablaggio della Cella Il problema principale che si è dovuto affrontare è stato quello di interfacciare i segnali della scheda SMARTALB con il mondo esterno. Tale problematica è stata risolta adottando dei dispositivi di tipo industriale comunemente usati per i segnali digitali di I/O per i PLC (Fig. 1.23 ). Essi si interfacciano dal lato PC con un cavo di tipo IDE mentre i fili che portano i segnali verso la periferia sono agganciati mediante viti. I cavi che sono stati adottati sono a 8 fili, e sono quelli utilizzati per le reti di computer, i quali bene si adattano a portare segnali di controllo . Nello schema dei collegamenti riportato nella pagina seguente, si evince come il punto in cui si incontrano i vari fili sia il pannello di controllo del nastro trasportatore (Fig. 1.21). In esso arrivano i 2 cavi utilizzati per i segnali delle pinze, più i 3 cavi collegati alla scheda SMARTLAB (Fig. 1.22). Dei 3 cavi verso la scheda di I/O, due vengono usati per i 15 segnali di ingresso, e uno per i 6 di uscita. La nomenclatura di tali segnali sarà maggiormente comprensibile quando si arriverà alla descrizione del software di controllo della cella, nel capitolo 3. ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Immagini fotografiche 33 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 1.6 Immagini Fotografiche Figura 1.13 - A sinistra il robot a 6 assi , a destra quello a 7 assi Figura 1.15 - Pannello operatore Figura 1.14 - Unità di controllo C3G-9000 ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Immagini fotografiche 34 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Figura 1.16 - Pinza pneumatica Figura 1.17 - Particolare dell'attacco falange Figura 1.18 - Compressore Figura 1.19 - Lubrificatore Figura 1.20 - Sensore per la pressione Figura 1.21 - Pannello di controllo del Nastro ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Immagini fotografiche 35 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Figura 1.22 - La scheda SMARTLAB Figura 1.23 - Dispositivo di Interfacciamento per la scheda Smartlab ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Immagini fotografiche 36 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Figura 1.24 - Robot a 6 assi in fase di prelievo pezzo dal vassoio di sinistra Figura 1.25 - Robot a 6 assi in fase di deposito pezzo sul nastro ______________________________________________________________________ Capitolo 1: La Cella Robotizzata – Immagini fotografiche 37 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Figura 1.26 - Robot a 7 assi in fase di deposito pezzo sul vassoio di destra Figura 1.27 - Disposizione dei pezzi a fine pallettizzazione ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time 38 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ _______________________________________________ CAPITOLO 2 : Architetture di Controllo Real‐Time _______________________________________________ Nel seguente capitolo si parlerà delle architetture Real‐Time, in particolare di RTLinux e della sua variante RTAI‐Linux, che è stato il sistema operativo utilizzato per lo sviluppo del software di controllo della cella robotizzata. ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time - Introduzione 39 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 2.1 Introduzione al Real‐Time Un sistema real‐time è un sistema in cui il corretto funzionamento non dipende soltanto dalla esattezza logica del risultato ma anche dal momento nel quale il risultato stesso viene prodotto. Sostanzialmente un sistema in tempo reale è un sistema che deve reagire ad un dato stimolo entro un tempo predefinito. Da un punto di vista puramente teorico la durata dell’intervallo che intercorre tra ricezione dello stimolo e risposta non ha importanza: un sistema in tempo reale non è necessariamente veloce, ma è fondamentale che sia deterministico, ossia che la risposta arrivi entro tolleranze precise e note a priori, non dopo ma nemmeno prima. Un interessante parallelo tra sistemi operativi tradizionali e sistemi operativi real‐ time può essere effettuato scambiando i termini logico e temporale nella descrizione delle loro caratteristiche peculiari. Un buon sistema operativo tradizionale deve garantire un elaborazione corretta dal punto di vista logico; è comunque possibile tollerare che la risposta arrivi leggermente in anticipo o leggermente in ritardo (ad esempio il risultato dell’elaborazione di un foglio di calcolo riportante il bilancio di un’azienda non deve arrivare esattamente 10 ms dopo aver battuto l’ultimo enter, ma è importante che i conti tornino nei limiti della precisione macchina). Un buon sistema operativo in tempo reale, invece, deve garantire un elaborazione corretta dal punto di vista temporale; è comunque possibile tollerare che la risposta sia leggermente incorretta (ad esempio la quantità di carburante da convogliare nel turboreattore di un aereo da combattimento non deve necessariamente essere esatta al grammo, ma è fondamentale che venga ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time - Introduzione 40 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ iniettata esattamente a 10 ms da quando il pilota ha impartito il comando per sincronizzarsi con i movimenti dei deflettori, pena una manovra errata). Questo non significa che ad un RTOS ( Real‐Time Operating System ) sia concesso dare risposte errate, ma solo che l’enfasi deve essere posta sul vincolo temporale. Questo tipo di sistema deve consentire allo sviluppatore di conoscere in anticipo i casi pessimi dei tempi di risposta ai vari servizi che offrono. Oggi, il real‐time gioca un ruolo cruciale nella nostra società, poiché un numero crescente di sistemi complessi si basano, in parte o completamente, su controlli computerizzati. Esempi di applicazioni che comportano elaborazioni soggette a vincoli temporali comprendono: • • • • • • • • • • controllo di impianti chimici e nucleari, controllo di processi di produzione complessi, sistemi di controllo di volo, acquisizione e monitoraggio di dati ambientali, sistemi di telecomunicazione, automazione industriale, robotica, sistemi militari, missioni spaziali, realtà virtuale. 2.1.1 Hard real‐time e soft real‐time Sostanzialmente questa distinzione si traduce nella quantificazione dei costi di una eventuale inesattezza temporale del sistema. In un sistema operativo tradizionale un errore di questo tipo può non avere importanza; un esempio potrebbe essere il foglio di calcolo che restituisce il risultato con ritardi che dipendono dalle altre applicazioni attive, dal fatto che si è spostato il mouse durante il calcolo o che è stato segnalato l’arrivo della posta elettronica: non ci sono costi associati a questa aleatorietà essenzialmente trasparente all’utente. In ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time - Introduzione 41 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ un sistema operativo soft real‐time l’inesattezza temporale è importante ma può comunque essere tollerata entro certi limiti; in un sistema hard real‐time anche un solo errore porta a costi eccessivi per l’utente se non addirittura alla perdita del sistema. Un esempio di sistema in tempo reale in una catena di montaggio può essere rappresentato da un robot manipolatore il cui braccio deve trovarsi sul pezzo nel momento in cui passa: non dopo ma nemmeno prima. Se mancare il pezzo comporta solo una riduzione della produzione per l’aumentare dei pezzi difettosi allora il sistema è soft real‐time; se invece comporta l’arresto della catena di montaggio perché il braccio ostacola lo scorrimento dei pezzi allora si tratta di hard real‐time I sistemi in hard real‐time non possono permettersi di compensare il caso pessimo con un buon andamento medio. Si è detto prima che in teoria la velocità non è una caratteristica di un RTOS: secondo questa linea di pensiero non entra nemmeno nella distinzione tra hard e soft real‐time; nella pratica, d’altronde, essa ha una importanza rilevante dato che al di sotto di una certa soglia un sistema, per quanto deterministico, non sarebbe in grado di assolvere alle funzioni richieste da una elaborazione in tempo reale. Ad esempio un sistema che si aggiorna esattamente ogni secondo non potrà certo essere impiegato per analizzare segnali con frequenze dell’ordine del kHz. ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – Processi, Thread e Task 42 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 2.2 Processi, Thread e Task Real‐Time Processo Un processo è un entità in esecuzione e la sua esecuzione deve progredire in modo sequenziale, vale a dire che in qualsiasi momento viene eseguita al massimo una sola istruzione alla volta. Un processo è qualcosa in più del codice di un programma , esso comprende l’attività attuale, rappresentata dal valore del program counter e dal contenuto dei registri di processore. Un processo comprende normalmente anche il proprio stack, che contiene a sua volta i dati temporanei, come parametri di subroutine, indirizzi di rientro e variabili temporanee, e una sezione dati contenente le variabili globali. Un programma di per se non è un processo; un programma è una entità passiva,come il contenuto di un file memorizzato sul disco, mentre un processo è un’entità attiva, con un program counter che specifica quale sia l’istruzione da eseguire e un insieme di risorse associate. Un qualsiasi processo è definito dalle risorse che utilizza e dalla locazione alla quale è in esecuzione . Thread Come già accennato, qualsiasi processo è definito dalle risorse che utilizza e dalla locazione alla quale è in esecuzione. Comunque esistono situazioni nelle quali sarebbe utile ammettere la condivisione delle risorse per consentirne poi l’accesso in concorrenza. Questa situazione è simile a quella che si verifica quando si invoca la system call fork specificando un diverso percorso di esecuzione, individuato da un nuovo valore del program counter, da eseguire all’interno del medesimo spazio di indirizzi. L’utilità di questo concetto è ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – Processi, Thread e Task 43 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dimostrata dal fatto che diversi sistemi operativi di nuova concezione hanno provveduto a fornire il supporto mediante il meccanismo dei thread. Un thread è l’unità base di utilizzo della CPU e consiste di un program counter, un insieme di registri e uno stack. Esso condivide con i thread ad esso associati le sezione di codice e dati, oltre che le risorse fornite dal SO, quali file aperti e segnali. L’insieme dei thread e dell’ambiente da essi condiviso prende il nome di task. Un processo tradizionale equivale ad un task dotato di un unico thread. Un task privo di thread non esegue alcun compito e ciascun thread deve esattamente essere contenuto in un task. Task Real‐Time Un task real‐time è una entità eseguibile di un lavoro che al minimo,è caratterizzato da un peggior caso di tempo di esecuzione e un vincolo di tempo. Ci sono 3 differenti tipi di task real‐time : • • • Periodici Aperiodici Sporadici Un task periodico è un task real‐time che è attivato (rilasciato) regolarmente a intervalli fissi di tempo (Periodo). Nel rispetto delle notazioni comuni il periodo è indicato con “T”. Normalmente, task periodici hanno vincoli di tempo indicanti che le loro istanze (job) devono eseguire una volta per periodo. Il vincolo di tempo è la deadline (scadenza) “d” che può essere minore , uguale o maggiore del periodo. Il caso più comune si ha quando la scadenza è uguale al periodo. Task aperiodici sono task real time che sono attivati irregolarmente ad un ritmo sconosciuto e possibilmente illimitato. Il vincolo di tempo è di solito la scadenza “d”. ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – Processi, Thread e Task 44 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Task sporadici sono task real‐time attivati irregolarmente con qualche conosciuta e finita frequenza. La frequenza finita è caratterizzata da un minimo periodo di “interarrivo” che è un minimo intervallo di tempo fra due task sucessivi. Il vincolo di tempo è di solito la scadenza “d”. Il tempo di rilascio ,”r”, è un istante di tempo in cui un job real‐time diventa pronto (o è attivato) per eseguire. Una scadenza ,”d”, è un istante di tempo entro cui il task deve completare. La scadenza può essere: • soft indica che è desiderabile finire l’esecuzione del task (job) dalla scadenza, ma non catastrofico se viene ritardato il completamento. • hard, indica che è vitale per la sicurezza del sistema che questa scadenza sia sempre incontrata. • firm, indica che il task dovrebbe completare dalla scadenza ,o non eseguire del tutto ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time –Linux Scheduling 45 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 2.3 Linux Scheduling Quando il kernel si trova ad effettuare un’operazione di scheduling, deve scegliere quale processo eseguire; questa circostanza si verifica o quando scade il quanto di tempo assegnato a un processo, o quando un processo kernel in esecuzione si è bloccato in attesa dellʹarrivo di un segnale di riattivazione. Linux adotta due distinti algoritmi di scheduling: uno è lʹalgoritmo time sharing per lʹequa condivisione del tempo di CPU da parte di più processi, e lʹaltro è concepito per elaborazione real‐time dove le priorità assolute sono più importanti dellʹequità. Si noti che lo scheduling real‐time di Linux è soft real‐ time, non hard real‐time; lo scheduler offre rigide garanzie sulle priorità relative dei processi real‐time, ma il kernel non fornisce alcuna garanzia sulla rapidità con cui un processo real‐time pronto per lʹesecuzione sarà effettivamente eseguito una volta che sia stato scelto dallo scheduler per lʹesecuzione: si ricordi a questo proposito che lʹesecuzione del codice kernel non può mai essere sospesa a causa di codice utente in attesa, perciò se un interrupt dovesse rendere eseguibile un processo real‐time mentre il kernel sta eseguendo una system‐call per conto di un altro processo, il processo real‐time dovrà rassegnarsi ad attendere la terminazione o il blocco della system‐call attualmente in esecuzione. Si vede quindi che la soluzione offerta da Linux standard per il rel‐time non è sufficiente per una gestione efficiente e sicura di un processo industriale nel mondo reale. A tale proposito sono state pensate e realizzate architetture che permettessero l’ingresso di Linux nel mondo reale dell’automazione. Nel prossimo paragrafo inizieremo a studiare una delle principali se non la più usata di queste architetture. ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – RTLinux 46 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 2.4 La soluzione RTLinux Real‐Time Linux (RTLinux), sviluppato dal New Mexico Institute of Tecnologyʹs (NMT), eʹ una versione di Linux che fornisce capacità hard real‐time. Un computer della NASA ha volato nellʹ occhio del ciclone George per raccogliere dati; il Jim Henson Creature Shop di Hollywood sta sviluppando un sistema RTLinux per controllare ʺanimatronicʺ usati nei film; RTLinux eʹ stato usato per editing video, PBX, controllo di robot e macchine utensili, e persino per fermare e riavviare il cuore in esperimenti medici. RTLinux fornisce la capacità di eseguire gestori di interrupt e speciali processi real‐time sulla stessa macchina su cui gira una versione standard di Linux. Questi processi e gestori di interrupt sono eseguiti indipendentemente da ciò che Linux sta facendo. Nel caso peggiore con RTLinux il tempo trascorso tra quando un interrupt hardware eʹ stato rilevato dal processore e quando il gestore di interrupt va in esecuzione eʹ al di sotto di 15 microsecondi, su di una macchina generica x86. Un processo periodico di RTLinux eʹ eseguito sullo stesso hardware con una precisione di ±17.5 microsecondi. Questi tempi hanno un limite nellʹ hardware, e con hardware migliore anche RTLinux diventa più preciso. Come termine di paragone, Linux standard impiega fino a 600 microsecondi ad avviare un gestore di interrupt, e può facilmente rimanere indietro fino a 20 millisecondi (20000 microsecondi) per un processo periodico. Uno studio ottimistico di MS‐Windows/NT non ha neppure tentato di misurare i tempi al di sotto del millisecondo, ed ha inoltre rilevato che i tempi di NT erano sostanzialmente gli stessi di Linux standard, mentre Windows98 ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – RTLinux 47 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ rimaneva indietro fino a 140 millisecondi in un processo periodico. Per essere giusti, ora esistono versioni di NT che usano la stessa tecnica di RTLinux, e queste sembrano raggiungere temporizzazioni che sono talvolta quasi altrettanto buone e in generale non peggiori oltre il 200% rispetto a RTLinux. Lʹutilità di RTLinux eʹ che estende lʹ ambiente standard di sviluppo UNIX permettendo di affrontare problemi real‐time. I gestori di interrupt di RTLinux infatti possono essere interfacciati ai processi ordinari di Linux o tramite una interfaccia device su cui Linux legge/scrive dati, o tramite memoria condivisa. Un processo standard Linux, che magari consiste in uno script della shell o in un programma in Perl, può raccogliere dati da un gestore o un processo real‐ time, lavorarci sopra e mostrare i risultati in X‐windows. Usare script in Perl per controllare un apparecchio real‐time da un normale pc puoʹ sembrare grottesco, ma funziona sorprendentemente bene. RTLinux funziona utilizzando il kernel del sistema operativo Linux come un normale processo, eseguito da un piccolo sistema operativo real‐time. In pratica Linux eʹ il processo in background del sistema operativo real‐time, e viene eseguito solo quando quest’ultimo non ha processi real‐time da eseguire. Il processo Linux non può mai bloccare gli interrupt o impedire di essere posto in attesa dal sistema operativo real‐time. La chiave tecnica di tutto ciò eʹ una emulazione software dellʹ hardware di controllo degli interrupt. Quando Linux invia allʹhardware il comando di disabilitare gli interrupt il sistema operativo real‐time intercetta la richiesta, la registra, e ritorna a Linux. Così a Linux non eʹ mai consentito di disabilitare veramente gli interrupt hardware: non importa in che stato Linux si trova, non potrà mai inserire ritardi nella gestione degli interrupt da parte del sistema operativo real‐time. ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – RTLinux 48 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Quando invece arriva una richiesta di interrupt dallʹhardware questa viene intercettata dal sistema real‐time, che decide cosa farne. Se dispone di un processo specifico per la gestione di tale interrupt glielo passa; altrimenti, nel caso lʹinterrupt non sia stato assegnato a un processo real‐time particolare o qualora questo processo abbia indicato che desidera condividere con Linux la gestione dellʹinterrupt, la richiesta eʹ marcata come ʺin attesaʺ. Se Linux aveva lasciato attivi gli interrupt, le richieste in attesa gli sono passate come emulazioni, e i suoi meccanismi standard di gestione vi operano normalmente, passando infine le eventuali modifiche allʹ hardware. Non importa cosa faccia Linux, se sta girando in kernel mode o sta eseguendo un normale processo utente, se sta lavorando con gli interrupt disabilitati o attivi: il sistema operativo real‐time sottostante eʹ sempre e comunque in grado di rispondere opportunamente allʹinterrupt. RTLinux scinde i meccanismi del kernel generico da quelli del kernel real‐time, in modo che entrambi possano essere ottimizzati indipendentemente secondo le rispettive finalità e facendo sì che il kernel real‐time possa essere mantenuto semplice e compatto. RTLinux eʹ progettato in modo che il suo kernel RT non debba mai essere lasciato in attesa della liberazione di risorse da parte di Linux. Il kernel RT non richiede memoria, neʹ condivide semafori o sincronizzazione di strutture dati, se non in situazioni strettamente controllate. Per esempio, i canali di comunicazione usati per trasferire dati tra i processi real‐time e quelli eseguiti da Linux sono di tipo non‐blocking dal lato RT: non esiste alcuna situazione in cui un processo RT debba attendere per trasmettere o ricevere dati. Il semi fallimento del Mars Lander fu causato dallʹ interazione tra di un processo real‐time e un servizio del sistema operativo, che ritenne fosse giusto ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – RTLinux 49 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ revocare dallʹesecuzione un processo. Un processo VxWorks si accaparrò il controllo di un semaforo e quindi lʹ altro processo ad alta priorità fu sospeso quando tentò di scrivere sulla pipe controllata da quel semaforo. RTLinux non ha nessun simile punto di sincronizzazione nascosto. Certamente non servirebbe a granché avere un sistema real‐time che non possa comunicare affatto con quello non real‐time, e perciò RTLinux fornisce allo scopo sia shared‐memory (anche se gestita piuttosto primitivamente) sia unʹ interfaccia col sistema del device layer di Linux, che consente ai processi Linux di inviare e ricevere dati ai processi real‐time tramite apposite entry in /dev. Una delle direttive principali nella progettazione di RTLinux eʹ: quanto più è demandato a Linux, e quanto meno eʹ lasciato al kernel RT, tanto meglio. Linux ha il compito di gestire le procedure di inizializzazione del sistema e dei device, e della gestione di ogni risorsa non condivisibile ad accesso dinamico. Lʹ inizializzazione delle periferiche può essere affidata a Linux perché non esiste nessuna esigenza particolare di real‐time in fase di avvio; la gestione delle risorse non condivisibili gli eʹ lasciata perché comunque qualsiasi flusso di esecuzione che possa essere bloccato in mancanza della particolare risorsa necessaria non eʹ sicuramente real‐time. Per esempio un programma real‐time non può assolutamente effettuare le chiamate malloc o kmalloc o qualsiasi altra funzione di allocazione di memoria: se il processo non ha richiesto allʹ inizio lʹallocazione statica di un certo quantitativo di memoria, non può avervi accesso. Per finire, RTLinux si affida al meccanismo di caricamento dei moduli kernel di Linux per installare i processi nel sistema real‐time, mantenendo così questʹultimo modulare ed estensibile. Caricare un modulo real‐time infatti non eʹ unʹ operazione real‐time, e può quindi essere lasciata senza problemi a Linux. ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – RTLinux 50 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Il compito del kernel RT eʹ solo quello di fornire ai programmi real‐time accesso diretto al nudo hardware, in modo che possano avere una latenza minima e il massimo potere computazionale quando necessario. ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – Linux-RTAI 51 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 2.5 Linux‐RTAI RTAI è stato sviluppato dal Dipartimento di Ingegneria Aerospaziale del Politecnico di Milano (DIAPM) come una variante del sistema RTLinux , nel momento in cui né lʹ unità in virgola mobile né lo scheduling periodico erano supportati da RTLinux. RTAI permette prestazioni deterministiche e preventive oltre a permettere lʹ uso di tutti i driver, applicazioni e funzioni contenute nellʹ ambiente standard Linux. 2.5.1 L’Architettura del sistema: RTHAL Da quanto letto nei paragrafi precedenti, il problema per un sistema di tipo real‐time è quello di bloccare e di reindirizzare gli interrupt, RTAI risolve tale problema attraverso il Real‐Time Hardware Abstraction Layer_ (RTHAL fig 2.28), che intercetta tutte le interruzioni hardware e le dirige o a standard Linux o a processi real‐time secondo i requisiti dello scheduler RTAI. Figura 2.28 - Architettura RTAI ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – Linux-RTAI 52 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ In particolare gli interrupt del processore (0‐31) sono gestiti da standard Linux, mentre RTAI gestisce gli interrupt hardware delle unità periferiche (32‐256). Gli interrupt che sono destinati a processi real‐time sono trasmessi direttamente agli stessi, mentre gli interrupt che non sono richiesti da alcun processo real‐ time sono inviati direttamente a standard Linux dove sono gestiti secondo le normali necessità. In questo modo, RTHAL fornisce la struttura su cui è montato RTAI, con piena capacità di controllo su Linux. Un componente chiave utilizzato da RTHAL è il vettore di interrupt detto anche ʺTABELLA DEI DESCRITTORI DI INTERRUPT” (IDT), questa tabella contiene i puntatori alle specifiche funzioni da invocare quando si verifica un determinato interrupt. Nel momento in cui il modulo RTAI viene caricato nel kernel, allʹinterno di RTHAL, si presentano le seguenti azioni: ¾ Viene generata una copia duplicata della tabella dei descrittori di interrupt e degli interrupt handler di standard Linux, che si trasforma in una tabella valida allo start di RTAI. ¾ Ridirezione degli interrupt di RTHAL, funzioni di abilitazione e disabilitazione degli interrupt, funzioni di salvataggio e ripristino dei flag agli equivalenti bloccati di RTAI. La disposizione di tutte le appropriate funzioni e dati in una singola struttura, l’RTHAL, rendendo facile intrappolare questi dettagli in modo da poterli cambiare dinamicamente tramite accessi da standard Linux e dal kernel hard real‐time. ¾ Il cambiamento dell’ handler functions in un nuovo idt_table nell’ RTAI dispatcher, in modo da permettere a RTAI il controllo hardware del sistema e dei relativi interrupt. ¾ Disposizione di un timer (8254 o APIC) per il dominio real‐time. In queste circostanze, Linux viene considerato soltanto come un processo di minima priorità nel dominio real‐time, ed eseguito solo quando non sono presenti processi real‐time a cui allocare la CPU. ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – Linux-RTAI 53 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 2.5.2 Implementazione dei servizi e dei processi Real‐ Time RTAI attraverso moduli caricabili nel kernel Linux offre i seguenti servizi real‐ time: scheduler, FIFO, memoria condivisa ed altri servizi solo quando necessari. Questa architettura modulare rende il sistema facilmente espansibile e personalizzabile secondo i servizi richiesti. Le applicazioni e quindi i processi sono implementati come moduli kernel. Si ricordi che l’ HAL ed i moduli real‐time di RTAI considerano, efficacemente, standard Linux come il processo di minima priorità, fornendo allʹ utente la capacità di inserire il processi real‐time di specifiche applicazioni ad una più alta priorità. In generale i processi real‐time vengono eseguiti come moduli kernel, dove hanno accesso diretto ai moduli di servizio RTAI e HAL. 2.5.3 RTAI Scheduling Fondamentale importanza nello scheduling dei processi é rivolta alla programmazione dei timer interrupt, in quanto permettono la corretta e precisa sincronizzazione dei task. RTAI supporta due differenti modalità di scheduling che definiscono la politica di attivazione dei task: • Periodica Con la modalità periodica (prevista di default) gli interrupt del timer si verificano regolarmente ad una definita frequenza, cioè il periodo fra due eventi successivi è costante nel tempo. Ciò indica che le istanze dei task periodici sono attivate negli istanti di tempo multipli del periodo definito. In questo modo una qualunque richiesta di scheduling si verifichi ad un istante che non è multiplo del periodo definito, viene soddisfatta al successivo tick del timer. La politica di ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – Linux-RTAI 54 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ attivazione periodica dà luogo ad una sequenza di istanze o job attivate periodicamente. Il timer è programmato solo una volta allʹatto di start, ottenendo un basso overhead, presentando però in certe circostanze una scarsa precisione nella sincronizzazione dei task. È compito del programmatore definire il periodo dei timer interrupt, in base alle caratteristiche dei task da schedulare. • One Shot La modalità one shot è molto diffusa nei sistemi di tipo real‐time, in quanto permette una sincronizzazione variabile dove ogni processo può essere cronometrato arbitrariamente, tenendo presente che deve essere eseguito una sola volta in corrispondenza di un predefinito istante tempo. In ambiente RTAI con modalità one shot la prossima scadenza del timer è programmata ad ogni interrupt, in corrispondenza della prossima istanza del primo task temporizzato con priorità maggiore o uguale a quello corrente, ricordando che durante lʹesecuzione del processo Linux deve essere garantito un periodo di tick minore o uguale a 10 mSec. Rispetto alla modalità periodica, one shot richiede due letture del CPU Time Stamp Clock e il setup del timer ad ogni interrupt, di conseguenza presenta un maggiore overhead ma, al contrario permette una precisa sincronizzazione dei task. 2.5.4 Hard e Soft Preemption La ʺpreemptionʺ ovvero la prelazione si identifica nella possibilità di sospendere lʹesecuzione di un processo per favorirne lʹesecuzione di un altro. Lo scheduler RTAI permette la prelazione ma solo da parte di task con più alta priorità rispetto a quello in esecuzione, ciò significa che task di pari priorità non ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – Linux-RTAI 55 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ possono prelazionarsi a vicenda. RTAI offre una Soft Preemption in cui la prelazione si verifica solo in certe situazioni, e una Hard Preemption in cui la prelazione è sempre garantita nel rispetto dellʹalgoritmo di scheduling utilizzato. Soft Preemption Nella modalità oneshot la prossima scadenza del timer è riprogrammata ad ogni interrupt, in corrispondenza della prossima istanza del primo task temporizzato con priorità superiore o uguale a quello corrente. Con la soft preemption prevista da RTAI, lo scheduler semplicemente esegue il task real‐time pronto a priorità maggiore finché questʹultimo non si sospende da solo, quindi riordina le code dei task temporizzati e dei task pronti e seleziona di nuovo il task pronto di massima priorità. Nel momento in cui non sono più presenti task real‐ time da schedulare il timer viene immediatamente riprogrammato per consentire lo scheduling del processo Linux. In questo modo lo scheduler è “non preemptive” per quanto riguarda task real‐time e “preemptive” per quanto riguarda il processo Linux. Con una tal politica lo scheduler RTAI riprogramma il timer solo durante lʹ esecuzione dei processi Linux, minimizzando il numero dei “lenti” setup del timer. In generale la Soft Preemption garantisce sempre una immediata prelazione del processo Linux quando si verifica la presenza di un task real‐time nello stato pronto. Al contrario la prelazione di task real‐time non è consentita, ciò significa che nel periodo di tempo in cui eseguono uno o più task in sequenza, non si verifica alcun interrupt del timer. Lʹ assenza di interrupt durante lʹ esecuzione di task real‐time provoca alcuni vantaggi, per esempio evita in calcolo, inutile in certi casi, del processo al quale ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – Linux-RTAI 56 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ allocare la CPU, nonché la continua riprogrammazione del timer. La Soft Preemption comporta a sua volta anche degli svantaggi, un processo veloce a più alta priorità comunque dovrà attendere la liberazione della CPU, anche se questa è occupata da un processo più lento e con una più bassa priorità Hard Preemption Ad ogni interrupt il timer viene riprogrammato in modo da garantire sempre tutte le prelazioni che si devono effettuare nel rispetto dell’algoritmo di scheduling utilizzato. Garantisce quindi una tempestiva prelazione del task in esecuzione nel caso in cui si verifichi la presenza di un task pronto prioritario, di conseguenza una perfetta sincronizzazione fra i task e il processo Linux. La costante riprogrammazione del timer comporta però in alcuni casi un notevole overhead, dovuto in parte al tempo impiegato per i sutup del timer (circa 2010 nSec), e in parte al calcolo del processo al quale allocare la CPU. ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – Linux-RTAI 57 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 2.5.5 Fondamenti di programmazione real‐time in ambiente RTAI L’unica differenza significativa fra lo sviluppo di processi real‐time e lo sviluppo di applicazioni standard nello spazio utente (che ignorano i problemi generali connessi alle applicazioni real‐time), sta nella loro compilazione e nelle caratteristiche dei moduli. Un processo real‐time si esegue come un modulo del kernel e quindi consiste in tre sezioni fondamentali di codice. A. funzione init_module() il modulo kernel deve sempre contenere una funzione init_module(), questa funzione è invocata dal comando Linux insmod ogni volta che il modulo viene caricato. Lo scopo di questa funzione è prepararsi alle successive invocazioni dei moduli funzione. Allʹinterno della funzione init_module() deve avvenire la creazione e lo start dei processi real‐time e del timer. B. funzione cleanup_module() La seconda funzione di modulo richiesta è la cleanup_module(). Questa funzione è invocata nel momento in cui un modulo viene rimosso dal kernel attraverso il comando rmmod. Tale funzione deve informare il kernel che il modulo è stato rimosso, così che nessuna delle sue funzioni sia più invocata. Alla rimozione del modulo, quindi al termine dellʹapplicazione, devono essere liberate tutte le risorse di sistema istanziate, arrestato il timer e cancellati i task real‐time precedentemente creati, ecc. C. codice specifico del task real‐time (composto dalle RTAI API) . Il codice specifico di un task implementa la parte run‐time dellʹapplicazione. Utilizza le RTAI api, le strutture dati ed i servizi per realizzare i task e le comunicazioni associate a Linux. RTAI offre una ampia gamma di API da utilizzare nel dominio real‐time che sono ampiamente descritte nel manuale “RTAI Programmino Guide” il cui riferimento si trova nella bibliografia. ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – REPLICS 58 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 2.6 Un esempio concreto: REPLICS Replics è un sistema di controllo composto da un driver ed un’applicazione d’interfaccia, con cui è possibile : • gestire e/o simulare contemporaneamente ed indipendentemente i robot industriali COMAU Smart‐3S e le unità di controllo aperte COMAU C3G‐9000; • gestire i sensori di forza ATI‐FT; • gestire il controllo cooperante delle due unit`a C3G‐9000; • monitorare, salvare su disco e graficare in tempo reale le posizioni, le correnti e le forze; • eseguire comandi e file di script per il linguaggio RPL (Replics Programming Language); • avere una vista 3D dei robot in tempo reale; • trasmettere dati attraverso le porte seriali e parallele; • controllare il tutto da una postazione remota. La figura 2.29 schematizza la set‐up attualmente utilizzata all’interno del laboratorio PRISMA per il quale Replics `e stato sviluppato. In particolare, sono evidenziati i collegamenti tra la macchina che esegue il driver Replics (denominata server Replics), le unità C3G ed i sensori ATI. ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – REPLICS 59 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Figura 2.29 - Set-Up Replics Replics è frutto del lavoro dell’ing. Nello Grimaldi ed è stato sviluppato a partire dal pacchetto software PC‐C3LINK, per molti anni impiegato con il sistema operativo MS‐DOS; il codice oggetto e gli eseguibili sono stati disassemblati, interamente riscritti ed ottimizzati per l’architettura a 32 bit, ed infine adattati per la variante hard real‐time RTAI del sistema operativo Linux. Inoltre, molti degli algoritmi di controllo sviluppati dal Dipartimento di Napoli sono stati riveduti e riscritti, e sono oggi richiamabili come moduli di controllo Replics. Nel lavoro di tesi Replics ha rappresentato l’interfaccia verso i robot Smart 3S. Infatti è stato scritto un modulo Replics che funge da device driver per il controllo dei robot, capace di ricevere ed eseguire i comandi impartiti dal modulo di controllo che gira all’interno di Soplics. Tale modulo, come tutto il sistema Soplics, sarà descritto per bene nel prossimo capitolo. Nelle figure 2.30 e 2.31 è possibile vedere rispettivamente la finestra principale dell’interfaccia grafica di Replics e la vista in 3D dei robot Smart 3S. ______________________________________________________________________ Capitolo 2 : Architetture di Controllo Real-Time – REPLICS 60 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Figura 2.30 - Interfaccia grafica di Replics Figura 3.31 - Replics : Vista 3D dei robot Smart 3S ______________________________________________________________________ Capitolo 3 : SOPLICS 61 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ _______________________________________________ CAPITOLO 3 : SOPLICS _______________________________________________ Nel seguente capitolo verrà ampiamente analizzato il software implementato SOPLICS (SOftware Plc under LInux Control System), sia dal punto di vista architetturale che funzionale. Inoltre verrà descritta l’interfaccia grafica che funge da sistema di supervisione per la cella robotizzata. ______________________________________________________________________ Capitolo 3 : SOPLICS – Architettura 62 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 3.1. Introduzione SOPLICS è un software progettato per creare un ambiente di controllo PC‐ Based, che renda possibile controllare la cella robotizzata del laboratorio PRISMA mediante una postazione PC senza dover utilizzare necessariamente il PLC. Nel seguente capitolo si vedrà dettagliatamente come ciò sia stato realizzato, partendo dall’architettura fino ad arrivare all’esecuzione di un modulo utente di controllo. 3.2. Architettura Soplics è suddiviso sia a livello logico‐strutturale che di programmazione in due distinte parti: ¾ Parte REALTIME ¾ Parte NON‐ REALTIME La parte non real‐time rappresenta l’interfaccia grafica, è stata programmata in C++ sfruttando le librerie grafiche QT della TrollTech , si occupa di supervisionare la cella e permette di compilare e caricare il modulo di controllo definito dall’utente. La parte real‐time rappresenta il cuore del programma; si occupa di eseguire il ciclo di controllo definito dall’utente e di comunicare con i driver che si interfacciano con i robot, le pinze e il nastro trasportatore, leggendo gli ingressi e scrivendo le opportune uscite. Le due parti comunicano attraverso delle FIFO ed un’area di memoria condivisa. Le FIFO sono tre, di cui due (FIFO_0 e FIFO_1) sono utilizzate per lo scambio bidirezionale di messaggi per la corretta esecuzione dei comandi ______________________________________________________________________ Capitolo 3 : SOPLICS – Architettura 63 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ provenienti dal pannello di comando, e una (FIFO_2) per la trasmissione e la stampa a video nell’interfaccia grafica di brevi messaggi di testo provenienti dai moduli della parte real‐time. Nella memoria condivisa invece, risiedono le variabili di stato del sistema, i valori dei segnali di I/O, e altre informazioni per la supervisione della cella. Di seguito (fig. 3.32) è riportato lo schema architetturale dell’intero sistema. Parte NON REAL-TIME SUPERVISIONE Pannello di Comando (Start-Stop Resume-Suspend) FIFO 0 Quadro Sinottico Gestione Modulo Utente Monitor FIFO 2 FIFO 1 Parte REAL-TIME Device Driver RTF Handler Robot Smart 3S (Replics) MAILBOX PLC-Manager thread 0 MAILBOX MAILBOX thread 1 Modulo Utente Smartlab I/O (nastro e pinze) MAILBOX MEMORIA CONDIVISA Figura 3.32 - Architettura di Soplics ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Principale 64 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 3.3. Parte Real‐Time La parte real‐time costituisce la parte più importante del sistema perché si occupa di eseguire il controllo vero e proprio della cella robotizzata. Essa è costituita da quattro moduli: ¾ modulo principale ¾ modulo device driver robot ¾ modulo device driver smartlab ¾ modulo utente Il modulo principale richiama periodicamente il ciclo di controllo contenuto nel modulo utente, e comunica con i due moduli device driver, per la lettura degli ingressi e l’aggiornamento delle uscite, attraverso delle mailbox. Inoltre i moduli comunicano con la parte non real‐time mediante FIFO e possono accedere ad un’area di memoria condivisa. Di seguito verranno analizzati i singoli moduli, descrivendo la loro struttura e le tecniche di implementazione che sono state adottate. 3.3.1 Modulo Principale Il modulo principale come già si è detto esegue praticamente la scansione del ciclo di controllo, ma non fa solo questo. Esso infatti si occupa di dichiarare i Task Real‐Time, di allocare e deallocare fisicamente la memoria condivisa, di inizializzare i device driver, di gestire gli eventi asincroni, ecc. Di seguito viene riportato uno schema che aiuta a capire la struttura del modulo (fig. 3.33). ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Principale 65 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ P a r t e D ic h ia r a t iv a TASK-Real-Time Puntatori a funzioni e variabili condivise MailBox - FIFO .... F u n z io n i d i s u p p o r t o addr_mbx splc_print suspend_system errore_handler init_driver event_handler resume_system rtf_in_handler read_input_sml write_output_sml read_input_rpl write_output_rpl plc_manager read_input_rpl l e g g e g l i i n g r e s s i read_input_sml r ic h ia m a la f u n z io n e d i c o n t r o llo c h e c k e v e n t i a s i n c r o n i event_handler a g g io r n a le u s c it e init_module Alloca la memoria necessaria inizializza il timer write_output_sml write_output_rpl cleanup_module Dealloca la memoria e rimuove i task Figura 3.33 - Struttura del Modulo Principale Innanzitutto nello schema vengono evidenziate le funzioni init_module e cleanup_module, che rappresentano le componenti principali di un modulo kernel, sia esso real‐time o meno. ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Principale 66 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Esse vengono richiamate rispettivamente quando viene caricato e scaricato un modulo in memoria. In particolare la init_module si fa carico dell’allocazione fisica della memoria condivisa e soprattutto inizializza il timer per i task real‐ time. Infatti i task implementati sono di natura periodica e il tick‐time che scandisce il momento in cui un task può essere attivato è fissato ad 1 ms. Di conseguenza il periodo di ogni task deve essere sempre un multiplo di un ms in modo da permettere la perfetta sincronizzazione del sistema. E’ da notare che in realtà il timer viene fissato attraverso un modulo ausiliario chiamato pulsar1 , in modo da essere un elemento indipendente e richiamabile all’occorrenza dai moduli caricati nel sistema. Questo permette per esempio di svincolare Soplics da Replics, il primo dei due, infatti, che richiama la funzione pulsar per fissare il timer, lo fa realmente, l’altro si adegua. Per quanto riguarda cleanup_module, tale funzione non fa altro che deallocare la memoria usata e cancellare i task creati, lasciando il sistema pulito. Passiamo adesso all’analisi dei componenti principali del modulo, successivamente verrà fatta un breve descrizione delle altre funzioni. Nella parte dichiarativa vengono definiti i puntatori agli indirizzi di memoria contenenti: • le strutture dati per l’I/O verso le periferiche; • le strutture dati per i messaggi inviati attraverso le mailbox e FIFO; • il vettore di stato del sistema; • i vettori usati per la memorizzazione delle fasi, transizioni e timer dell’algoritmo di controllo; • il vettore contenente le informazioni relative al pezzo per il sistema di supervisione; ______________________________________________________________________ 1 Pulsar è il risultato di un aggiornamento di Replics Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Principale 67 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Inoltre vengono definiti i seguenti task real‐time: splc_task, è il task principale, ad ogni sua attivazione viene eseguita la funzione plc_manager che esegue il ciclo di controllo. sml_task , è il task attivato per la comunicazione con il driver della scheda Smartlab di I/O event1_task, event2_task, event2_task , sono i task legati agli eventi asincroni. Infine vengono definiti i puntatori a funzioni, che permettono una notevole dinamicità e indipendenza di codice. Tre di questi vengono usati per le funzioni legate agli eventi asincroni e uno, il più importante, punta alla funzione contenente il codice del ciclo di controllo Tale soluzione permette di svincolare l’utente dal codice sorgente di Soplics, permettendo di scrivere la funzione di controllo in un modulo a parte, di compilarlo e caricarlo in memoria separatamente da tutto il resto. Infatti come si evince dall’analisi del codice sorgente, nella funzione principale plc_manager, una volta eseguite le funzione per la lettura degli ingressi, alla voce “richiama la funzione di controllo”, nello schema di figura 3.31, corrisponde la chiamata tramite puntatore alla funzione contenuta nel modulo utente. Una volta finito l’esecuzione del codice utente, il programma ritorna alla funzione principale e prosegue la sua esecuzione, ossia controlla l’eventuale attivazione di eventi asincroni, tramite la funzione event_handler e aggiorna le uscite. Una volta finita la sua esecuzione il task va a “dormire”, ossia rimane inattivo per un periodo che può essere settato in base alle esigenze di controllo. Se si diminuisce troppo tale periodo, alzando quindi la frequenza di esecuzione del task di controllo, si rischia di rallentare in modo drastico le normali attività di un sistema operativo. Questo è perfettamente normale, perché il task è di tipo ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Principale 68 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ real‐time e quindi avrà sempre una priorità maggiore rispetto ad un qualunque processo di Linux. Quindi bisogna settare bene tale periodo, tenendo conto, in teoria, anche del tempo di esecuzione del codice scritto dall’utente per il controllo della cella. Quest’ultimo però , nel caso specifico, ha un peso relativamente piccolo, data la potenza di calcolo che si ha a disposizione. Alla fine, in modo empirico, il periodo è stato fissato a 35ms, valore ottimale per una corretta esecuzione del ciclo di controllo. Di seguito vengono elencate le altre funzioni del modulo e una breve descrizione del loro ruolo. addr_mbx Restituisce lʹindirizzo delle mailbox usate per i device driver. splc_print Si occupa di trasferire tramite la FIFO_2 brevi messaggi di testo dei moduli verso l’interfaccia grafica. suspend_system Sospende tutto il sistema fermando l’esecuzione del ciclo di controllo e rilasciando le periferiche. error_handler Si occupa della gestione di eventuali errori (per esempio la non risposta in tempo utile da parte di un device, il mancato caricamento del modulo utente ecc..), comunicando il tipo di errore che si è verificato e la sua conseguenza (se per esempio si è dovuto arrestare il sistema). init_driver Si occupa di inizializzare le periferiche settando opportuni valori, in pratica per adesso si limita solo ad eseguire una prima comunicazione con esse, fungendo quindi da check‐up prima dell’esecuzione di un ciclo di controllo. ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Principale 69 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ read_input_sm Legge gli ingressi della scheda Smartlab, copiandoli nelle strutture dati corrispondenti. write_output_sml Scrive le uscite sulla scheda Smartlab, copiandoli dalle strutture dati corrispondenti. read_input_rpl Legge le variabili di stato dei robot, copiando i valori nelle rispettive strutture dati. write_output_rpl Invia i comandi al modulo di controllo per i robot. event_handler Gestore degli eventi asincroni, controlla se un evento si è attivato e in tal caso crea il task per l’esecuzione della funzione legata all’evento stesso. resume_system Porta il sistema nello stato pronto, inizializzando i device driver e dando inizio alla scansione del ciclo di controllo. rtf_in_handler E’ il gestore della FIFO_1 di ingresso al modulo. Non appena si riceve un messaggio (FIFO non vuota) dal pannello di comando situato nella parte non real‐time, si attiva, lo riceve ed esegue l’azione corrispondente al comando.che può essere Resume / Suspend o Start / Stop Nel primo caso viene richiamata la funzione appropriata (resume_system per l’attivazione e suspend_system per la sospensione del sistema), mentre nel caso di Start / Stop non si fa altro che settare il valore 1/0 nelle corrispondenti locazioni di memoria, poi sarà compito dell’algoritmo di controllo interpretarle e decidere l’azione da eseguire. ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Device-Driver Robot 70 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 3.3.2 Modulo Device Driver Robot Per l’interfaccia Soplics/robot si è scritto un modulo ad hoc che sfrutta le librerie di Replics. La struttura di questo modulo è riportata di seguito (fig. 3.34). P a r t e D ic h ia r a t iv a Puntatori a funzioni e variabili condivise MBX .... t h r e a d 0 - robot6assi t h r e a d 1 - robot7assi attesa sulla mailbox SI attesa sulla mailbox messaggio ricevuto messaggio ricevuto esecuzione dell'azione corrispondente al comando esecuzione dell'azione corrispondente al comando comando eseguito con successo comando eseguito con successo NO ERRORE! arresto del sistema init_module Alloca la memoria necessaria e collega i puntatori alle funzioni SI NO ERRORE! arresto del sistema cleanup_module Dealloca la memoria Figura 3.34 - Struttura del modulo driver per i robot ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Device-Driver Robot 71 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Come nel modulo principale sono presenti la parte dichiarativa, la init_module e la cleanup_module. Nella parte dichiarativa viene definito il vettore di stato condiviso, le intestazioni delle funzioni e il puntatore alla mailbox utilizzata dal driver. Tale puntatore punterà all’indirizzo di memoria ottenuto tramite l’invocazione della funzione addr_mbx definita nel modulo principale e dichiarata qui come extern. La init_module ha l’importante compito, oltre all’allocazione (non fisica) della memoria, di collegare i puntatori (denominati simbolicamente thread_0 e therad_1) alle funzioni (robot6assi e robot7assi), per permettere l’attivazione ed esecuzione del modulo robot nel contesto del modulo principale. Infatti sarà quest’ultimo che, alla ricezione del comando di resume, attiverà ed inizializzerà il modulo per Replics. La cleanup_module invece dealloca semplicemente la memoria. Una volta attivato e inizializzato il modulo, andranno in esecuzione i due thread associati ai rispettivi robot. Questi thread naturalmente condivideranno il codice scritto nel modulo, ma a ciascuno di essi è associato una funzione separata e distinta, e diverso sarà il contesto in cui essi opereranno. Infatti le due funzioni (robot6assi e robot7assi) hanno lo stesso identico codice ma vengono eseguite in due contesti separati. Per chiarire meglio il concetto, in ciascuna funzione c’è la medesima riga di istruzione: in_mbx=(MBX*)addr_mbx(r); ma la variabile ‘r’ assumerà il valore 0 se chiamata nel contesto del thread 0 e 1 se invocata nel contesto del thread 1. Ad essere rigorosi, la scrittura di due funzioni con codice identico è ridondante e non necessaria, ma la soluzione adottata rende il codice concettualmente più comprensibile e offre una maggiore robustezza. ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Device-Driver Robot 72 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Infatti i due thread condividono sì lo stesso codice, ma accedono a parti separate e distinte senza crearsi così la minima interferenza. Una volta ottenuto l’indirizzo delle rispettive mailbox, i due thread si mettono in attesa di ricevere i comandi. Ricevuto il messaggio1, questo viene aperto e si hanno principalmente due informazioni: la prima è l’indirizzo di ritorno a cui mandare il messaggio di avvenuta ricezione, e la seconda, più importante, è il comando da eseguire. I comandi che si possono eseguire sono molto semplici ( accensione e spegnimento dei motori e movimento dei robot), e utilizzando il costrutto case del C, si è quindi associato il comando ricevuto (i cui codici sono definiti con delle macro) con le rispettive API della libreria di Replics. Il meccanismo è quindi semplice, ma per il suo funzionamento si è dovuti adottare un piccolo ma decisivo stratagemma. Infatti, quando in una fase viene eseguita un’azione, per esempio un DRIVE_ON (accensione motori), tale comando viene inviato ad ogni esecuzione del ciclo di controllo indipendentemente dal fatto che il robot sia pronto o meno a riceverlo, e questo accade finché non si passa in un’altra fase. Tutto questo provoca un “bombardamento” continuo della mailbox con conseguenze indefinite ma sicuramente indesiderate. Per evitare tale comportamento, si è usata una variabile condivisa, che funge da semaforo, attraverso la quale il thread avverte il modulo principale se il robot è già occupato in azioni o meno. Solo nel caso in cui il robot risulta libero i comandi vengono inviati realmente. In questo modo, l’aggiornamento delle uscite avviene correttamente e soprattutto non si va ad alterare minimamente la normale esecuzione del ciclo di controllo. ____________________________________________________________________________________ 1 La struttura dati del messaggio è semplicemente un record costituito da vari campi Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Device-Driver Smartlab 73 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 3.3.3 Modulo Device Driver Smartlab La scrittura del codice per il modulo driver della scheda di I/O della Smartlab, è risultata meno problematica che per i robot. La struttura del modulo è riportata di seguito (fig. 3.35), e come si vede ricalca quella usata per la gestione dei robot. P a r t e D ic h ia r a t iv a Puntatori a funzioni e variabili condivise MBX .... m b x _ h a n d le r attesa sulla mailbox messaggio ricevuto vengono scritte o lette le porte di I/O SI Operazione di I/O eseguita con successo NO ERRORE! arresto del sistema init_module cleanup_module Alloca la memoria necessaria e collega i puntatori alle funzioni Dealloca la memoria Figura 3.35 - Struttura del modulo driver per la scheda Smartlab ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Device-Driver Smartlab 74 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Anche qui c’è una parte dichiarativa in cui vengono definiti le strutture dati condivise, i puntatori per l’indirizzo della mailbox e per la funzione di gestione della stessa. In init_module viene allocata la memoria e collegato il puntatore (*sml_mbx_manager), definito nel modulo principale, alla funzione per la gestione della mailbox (mbx_handler) scritta nel modulo smartlab. Tutto questo sempre per permettere l’attivazione del task real_time, relativo al driver smartlab, dal modulo principale quando arriva il comando di resume. La cleanup_module come al solito dealloca la memoria quando il modulo viene scaricato dal sistema. Il modulo lavora nello stesso modo di quello visto nel paragrafo precedente, una volta attivato, si mette in attesa sulla mailbox corrispondente. Arrivato il messaggio, lo riceve, spedisce il messaggio di conferma dell’avvenuta ricezione e decide quale operazioni effettuare. In questo caso le operazioni sono più a basso livello rispetto a quelle viste per i robot. Infatti o si esegue un’operazione di Input ( identificata con GET_PORTS ) , e in questo caso non si fa altro che leggere le porte di ingresso della scheda, oppure un’operazione di Output ( SET_PORTS ), ossia si scrive la maschera sulle porte di uscita. Queste due operazione vengono fatte semplicemente usando le istruzioni inw(indirizzo_porte) e outw(val_out, indirizzo_porte), rispettivamente per la lettura e la scrittura delle porte, dove indirizzo_porte rappresenta l’indirizzo assegnato alla scheda smartlab (3E0H), e val_out rappresenta la maschera di 1/0 da inviare alle porte di uscita. ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Utente 75 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 3.3.4 Modulo Utente L’obiettivo principale del lavoro di tesi era quello di fornire un ambiente operativo in cui poter scrivere un algoritmo di controllo per la cella avendo a disposizione i segnali di ingresso e uscita per comandare i robot, le pinze e il nastro trasportatore. Soplics mette a disposizione, attraverso macro e funzioni di libreria, gli strumenti necessari per il controllo completo della cella robotizzata, dando la possibilità di scrivere un modulo utente senza dover conoscere necessariamente la struttura interna dell’intero sistema. Di seguito viene riportato lo schema di un generico modulo utente (fig. 3.36). #define TIMER_ON #define ROBOT_ON #define EVENT1_ON #define EVENT2_ON #define EVENT3_ON #include <splc_ctrlmod.h> int scan_loop() { ... } static void event1_fun(int e) { .... } static void event2_fun(int e) { .... } static void event3_fun(int e) { .... } Figura 3.36 - Schema per la scrittura di un modulo utente ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Modulo Utente 76 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Prima di tutto si nota nella parte dichiarativa la definizione di alcune MACRO, queste sono direttive al compilatore e facoltative, ossia vanno aggiunte solo se si desidera utilizzare i componenti corrispondenti. Per esempio nello schema generale di prima vengo definiti tutti i componenti, questo significa che il modulo userà le strutture dati per i timer, le librerie per i robot e sfrutterà tutti e tre gli eventi asincroni messi a disposizione. Il codice corrispondente al ciclo di controllo dovrà essere necessariamente scritto all’interno della funzione scan_loop(), simile al main di un generico programma C. Le altre tre funzioni event1_fun, event2_fun, event3_fun, dovranno contenere il codice del compito da eseguire al verificarsi dei corrispondenti eventi asincroni. Infine deve essere incluso l’header <splc_ctrlmod.h>, contenete le macro e le funzioni di libreria, e quindi vitale per la corretta compilazione del modulo. Naturalmente essendo prima di tutto un modulo kernel scritto in C, a tale schema si possono aggiungere definizioni di variabili e funzioni a piacimento dell’utente, questo proprio a conferma della filosofia che ha guidato tutto il progetto. Una cosa molto importante da dire è che la definizione delle variabili deve essere necessariamente di tipo static, altrimenti perderebbero il loro valore ad ogni nuova esecuzione della funzione scan_loop del ciclo di controllo. Nel prossimo paragrafo verranno descritte le macro e le funzioni che si possono usare nel modulo utente e che permettono, quindi, di controllare i componenti della cella robotizzata. ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Macro e Funzioni 77 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 3.3.5 Macro e Funzioni Stato del Sistema Per specificare lo stato del sistema, si usa: SYS_STATUS = stato del sistema dove per stato del sistema si indica: PALLET DEPALLET PLC_READY PLC_SUSPEND PLC_ALLARM → → → → → Pallettizzazione Depallettizzazione Sistema pronto Sistema sospeso Sistema in allarme Il tipo di allarme che si è verificato si indica con: ALLARM_TYPE = tipo di allarme dove tipo di allarme può indicare: TIME_OUT_AVA TIME_OUT_IND TIME_OUT_OPEN_PINCER_0 TIME_OUT_CLOSE_PINCER_0 TIME_OUT_OPEN_PINCER_1 TIME_OUT_CLOSE_PINCER_1 PRESS_WARNING → → → → → → → malfunzionamento fotocellule di destra malfunzionamento fotocellule di sinistra la pinza 0 non si è aperta la pinza 0 non si è chiusa la pinza 1 non si è aperta la pinza 1 non si è chiusa pressione insufficiente Infine in caso di mancato riconoscimento del pezzo si setta l’allarme specifico tramite la macro: ALLARM_PEZ=1 ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Macro e Funzioni 78 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Fasi e Transizioni Per le fasi e le transizioni dell’algoritmo SFC di controllo vengono usate le seguenti macro: X(i) TR(i) CLEAR_TR Il loro uso è immediato , infatti per settare una transizione basta scrivere: X(1)=1; e per verificare se ci si trova in una determinata fase basta un semplice if : if (X(1)) { … azioni da eseguire … } mentre per attivare una transizione si richiama prima la macro CLEAR_TR, che le resetta tutte e poi semplicemente si setta la specifica transizione : CLEAR_TR; TR(1)=1; Timer La gestione dei timer avviene mediante tre funzioni: void load_timer(int num, RTIME value) static RTIME timer(int num) static void reset_timer(int num) La prima serve per impostare un valore, che può essere espresso in secondi (SECs) o millisecondi (mSECs), in un timer specifico (se ne hanno a disposizione 30), per esempio: load_timer(1,5*SECs); carica il timer numero 1 a 5 secondi. ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Macro e Funzioni 79 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ La seconda funzione serve per verificare se un timer è scaduto o meno. Nel primo caso ritorna zero altrimenti ritorna quanto rimane allo scadere del timer in millisecondi, per esempio: If (!timer(1)) { … azione …} Ossia se è scaduto il timer 1 allora fai una certa azione. L’ultima funzione serve invece per resettare un timer e permettere quindi la sua programmazione, è buona cosa richiamarla prima di usare un timer: reset_timer(1) load_timer(1,5*SECs); E’ da notare che ripetute chiamate di load_timer non hanno effetto se non si è prima resettato il timer, questo per salvaguardare il valore iniziale impostato per il timer necessario per verificare se sia scaduto o meno il tempo. Eventi Asincroni Infine per gli eventi asincroni si hanno le macro: EVENT1 EVENT2 EVENT3 Che vengono usate semplicemente scrivendo: EVENT1=evento Dove evento, può essere un segnale o una funzione che restituisce un valore 1/0 Naturalmente 1 vuol dire che l’evento si è verificato 0 altrimenti. ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Macro e Funzioni 80 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Nastro e Pinze Di seguito vengono elencati le macro per i segnali sulle porte di ingresso della scheda Smartlab usate per il nastro trasportatore e le pinze: Input Smartlab descrizione macro FD1 FD2 FD3 FD4 S1 KT KMA KMI EMERG QM PRESS_OK SMA_0 SMC_0 SMA_1 SMC_1 sensore della prima cellula fotoelettrica sensore della seconda cellula fotoelettrica sensore della terza cellula fotoelettrica sensore della quarta cellula fotoelettrica sensore induttivo centrale alimentazione pannello elettrico nastro segnale nastro in movimento in avant segnale nastro in movimento all'indietro segnale di emergenza (pressione del tasto situato sul pannello elettrico) segnale di corrente assente per surriscaldamento termico sensore di minima pressione per il buon funzionamento delle pinze Stato Mano Aperta pinza su robot a 6 assi Stato Mano Chiusa pinza su robot a 6 assi Stato Mano Aperta pinza su robot a 7 assi Stato Mano Chiusa pinza su robot a 7 assi Tali macro restituiscono il valore 0 se il segnale corrispondente è basso, il valore 1 se è alto: if(FD3) { …azione …} ossia se è alto il segnale della fotocellula 3 allora esegui l’azione. ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Macro e Funzioni 81 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Analogamente per i segnali di uscita si hanno le seguenti macro: macro Output Smartlab descrizione Comando per far andare il nastro in avanti AVA Comando per far andare il nastro all’indietro IND Comando apertura pinza 0 su robot a 6 assi OPEN_PINCER_0 Comando chiusura pinza 0 su robot a 6 assi CLOSE_PINCER_0 Comando stato rilassato per la pinza 0 RELAX_PINCER_0 Comando apertura pinza 1 su robot a 7 assi OPEN_PINCER_1 Comando chiusura pinza 1 su robot a 7 assi CLOSE_PINCER_1 Comando stato rilassato per la pinza 1 RELAX_PINCER_1 Per esempio per azionare il motore del nastro in avanti basta scrivere : AVA=1; Per aprire la pinza 0, situata sul robot a 6 assi : OPEN_PINCER_0=1; Per comandare lo stato rilassato per la pinza 1 : RELAX_PINCER_1; ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Macro e Funzioni 82 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Robot I comandi per i robot, come si è detto in precedenza, sono molto semplici e diretti, di seguito le macro utilizzate: macro DRIVE_ON(i) MOVE_TO(i) DRIVE_OFF(i) Output Robot descrizione Accensione dei motori Movimento Robot Spegnimento dei motori Il parametro ‘ i ’ può assumere il valore 0 per al robot a 6 assi, e il valore 1 per il robot a 7 assi, per esempio: DRIVE_ON(0) accende i motori del robot a 6 assi, e MOVE_TO(0) lo fa muovere verso la posizione settata. Per settare la posizione da raggiungere si hanno le seguenti due funzioni: static int set_pos(double *p,int rob) static int is_set_pos(double *p,int rob) La funzione set_pos serve per settare la posizione da raggiungere, mente la seconda is_set_pos, restituisce 1 se la posizione è stata settata correttamente per il robot specificato; il primo parametro rappresenta il puntatore al vettore contenente i valori dei giunti, e il secondo indica il robot di riferimento. Per esempio: set_pos(rob_pos,0) setta la prossima posizione da raggiungere, rappresentata dal vettore denominato rob_pos, per il robot 0 a 6 assi. ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Macro e Funzioni 83 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Inoltre è definita un’ulteriore macro che serve in caso di allarme e permette di fermare correttamente i robot, se in movimento, senza causare conseguenze indesiderate, essa è la seguente: MOVETO_EXIT(i) dove naturalmente il parametro ‘i’ indica il robot. Per gli ingressi, che permettono di conoscere lo stato dei robot, si hanno le seguenti macro: Input Robot descrizione macro IS_DRIVE_ON(i) MODE(i) IS_POS_OK(i) IS_STOP(i) GET_ERROR(r,i) POS_NOW(r,i) Restituisce 1 se il motore è acceso Restituisce la modalità di funzionamento dei Robot Restituisce 1 se è stata raggiunta la posizione Restituisce 1 se è stato ricevuto un segnale di STOP Vettore degli errori restituiti dai robot Restituisce la posizione corrente dei giunt Come prima ‘ i ’ serve ad indicare il robot, ad eccezione però per le ultime due macro in cui è il parametro ‘ r ’ ad assumere questo ruolo mentre la i serve ad indicare il tipo di errore, nel caso di GET_ERROR, e il numero del giunto, nel caso di POS_NOW. I tipi di errore sono indicati con: ERR_DRIVE_ON ERR_DRIVE_OFF ERR_GET ERR_SET ERR_GEN Errore nell'accendere i motori Errore nello spegnere i motori Errore nel prendere i riferimenti Errore nel settare i riferimenti Errore generico L’uso come al solito è molto semplice e diretto: if(IS_DRIVE_ON(1)) { …azione … } ossia se il motore del robot 1, quello a 7 assi, è accesso allora esegui l’azione. ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Macro e Funzioni 84 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ MACRO di Supervisione Infine vengono definiti le macro che portano informazioni per la parte non‐realtime di supervisione. Di seguito sono riportate quelle per indicare se il robot è in movimento oppure se è fermo, in quale posizione si trova: IN_MOV P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 SUL_NASTRO robot in movimento posizione neutrale robot posizionato sul pezzo 1 robot posizionato sul pezzo 2 robot posizionato sul pezzo 3 robot posizionato sul pezzo 4 robot posizionato sul pezzo 5 robot posizionato sul pezzo 6 robot posizionato sul pezzo 7 robot posizionato sul pezzo 8 robot posizionato sul pezzo 9 robot posizionato sul pezzo 10 robot posizionato sul pezzo 11 robot posizionato sul pezzo 12 robot posizionato sul nastro trasportatore Mentre per il pezzo vengono usate le seguenti macro: NEUTRO ‘N’ VERDE ‘V’ GRIGIO ‘G’ BIANCO ‘B’ NO_PEZ ‘X’ COL_PEZ VS_P(i) VD_P(i) PEZ_NAT USER_POS_PEZ pezzo di colore neutro (azzurro) pezzo di colore verde pezzo di colore grigio pezzo di colore bianco nessun pezzo colore del pezzo pezzi sul Vassoio di Sinistra pezzi sul Vassoio di Destra numero di pezzi presenti sul nastro posizione definita dall’utente nel caso in cui il pezzo non viene riconosciuto ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Real-Time – Macro e Funzioni 85 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ La posizione dei pezzi sui due vassoi è stata fissata secondo il seguente schema: Vassoio di Sinistra Vassoio di Destra P11 P9 P12 P10 P11 P9 P12 P10 P7 P8 P7 P8 P5 P6 P5 P6 P3 P1 P4 P2 P3 P1 P4 P2 Infine la pressione dei pulsanti START/STOP sul pannello di comandi dell’interfaccia grafica, da parte dell’operatore, viene segnalata attraverso le macro omonime: START STOP ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Non Real-Time – Interfaccia Grafica 86 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 3.4. Parte Non‐RealTime La parte non‐realtime rappresenta il sistema di supervisione della cella con cui è possibile: ¾ caricare e compilare un modulo utente di controllo ¾ configurare i componenti della cella ¾ monitorare e controllare lo stato della cella, attraverso un quadro sinottico 3.4.1 Descrizione dell’Interfaccia Grafica L’interfaccia grafica è stata realizzata in C++ utilizzando le librerie Qt1 della TrollTech, che è simile all’ambiente di sviluppo VisualBasic della Microsoft®. Attraverso di essa si può avere il controllo completo della cella, dal caricamento del modulo di controllo fino alla gestioni degli allarmi. Il codice, anche se abbastanza lungo, ha di base una logica molto semplice. Infatti periodicamente viene attivato un processo che non fa altro che leggere i dati contenuti nella memoria condivisa e aggiornare graficamente il quadro sinottico. Oltre a ciò, naturalmente, interagisce con il task real‐time attraverso le FIFO descritte nei paragrafi precedenti. L’interfaccia è divisa in varie sezioni, legate tra di loro da una certa sequenzialità, per esempio il quadro sinottico risulta inattivo se non è stato prima caricato un modulo e non si sono configurati i componenti da utilizzare. ______________________________________________________________________ 1 La libreria Qt è alla base dell’ambiente desktop KDE di Linux. Capitolo 3 : SOPLICS – Parte Non Real-Time – Interfaccia Grafica 87 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Appena lanciato il programma si ha la seguente finestra grafica (fig. 3.37) : Figura 3.37 - Soplics : Configurazione Essa rappresenta la sezione Configurazione, e in particolare la sottosezione riguardante il caricamento e/o compilazione di un modulo utente. Per la compilazione di un modulo la procedura è semplice, basta cliccare su “Sfoglia…” selezionare il file sorgente nella finestra che si è aperta e successivamente cliccare su “Compila”, vengono mostrati anche eventuali errori di compilazione. Invece per il caricamento in memoria bisogna cliccare su “Carica Nuovo Modulo” e selezionare il nome del file desiderato. _____________________________________________________________________________________ Capitolo 3 : SOPLICS – Parte Non Real-Time – Interfaccia Grafica 88 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Fatto ciò si passa alla sottosezione Dispositivi Usati, mostrata in fig. 3.38, in cui bisogna indicare quali sono i dispositivi che il modulo di controllo utilizzerà. Figura 3.38 - Soplics : Scelta dei dispositivi Per la scheda Smartlab, è possibile selezionare anche la modalità di funzionamento: I/O Simulato I/O Reale Input Simulato Output Simulato _____________________________________________________________________________________ Capitolo 3 : SOPLICS – Parte Non Real-Time – Interfaccia Grafica 89 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Anche per i robot esiste una modalità simulata e una reale, ma bisogna settarla direttamente in Replics. In questo modo c’è la possibilità di provare il funzionamento del modulo implementato prima in modalità simulata e poi, una volta verificata la sua correttezza, passare alla modalità reale, evitando così pericoli gravi per le apparecchiature. Completata la fase di configurazione, si passa alla sezione di supervisione, selezionando la linguetta denominata SCADA1, viene così visualizzato il quadro sinottico relativo alla cella (fig. 3.39). Figura 3.39 - Soplics : Quadro Sinottico _____________________________________________________________________________________ 1 SCADA Supervisory Control And Data Aquisition, ossia sistema di controllo e acquisizione dati. Capitolo 3 : SOPLICS – Parte Non Real-Time – Interfaccia Grafica 90 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Il quadro sinottico è diviso in vari riquadri ciascuno dedicato ad un singolo dispositivo o specifica funzione. In alto a destra c’è il riquadro dedicato allo Stato del Sistema, in cui è possibile sapere se il sistema è pronto per l’esecuzione, se è stato fermato, se si trova nella fase di pallettizzazione o depallettizzazione, inoltre riporta anche il nome del modulo utente caricato in memoria e se si sono verificati degli errori. Subito a destra vengono visualizzati i segnali di output, segnalandone la loro attivazione. Segue sotto la rappresentazione del Nastro Trasportatore, in cui è possibile conoscere lo stato delle fotocellule, del motore, dell’alimentazione, se ci sono state eventuali emergenze e infine la disposizione dei pezzi sui vassoi in tempo reale, segnalando anche il numero di pezzi presenti sul nastro. I riquadri per i robot mostrano lo stato dei motori se accesi o spenti (Drive ON/OFF) , la modalità di funzionamento (nel nostro caso sempre la numero 6, quella relativa allo spazio dei giunti), il comando che si sta eseguendo, eventuali errori, la posizione dei robot sia in termini globali, ossia se è in movimento oppure posizionato su un pezzo o sul nastro, sia in termini dei singoli giunti, ed infine la spia STOP per segnalare la pressione del pulsante di arresto sull’unità di controllo C3G‐9000. Dal riquadro per le pinze è possibile conoscere lo stato della mano, se aperta (spia SMA accesa) o chiusa (spia SMC) e se la pressione per il buon funzionamento del circuito pneumatico è sufficiente (spia verde accesa). Infine al centro sono posizionati i pulsanti del pannello di comando:. o START/STOP o RESUME/SUSPEND ______________________________________________________________________ Capitolo 3 : SOPLICS – Parte Non Real-Time – Interfaccia Grafica 91 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Inizialmente solo il pulsante di RESUME è attivo e questo è normale perché il sistema deve essere mandato in esecuzione e inizializzato. Una volta premuto viene inviato il comando, attraverso la FIFO, verso la parte Real‐Time che attiva i task necessari all’esecuzione della scansione periodica dell’algoritmo di controllo e alla comunicazione con le periferiche. A questo punto il sistema è attivo ed evolve secondo l’algoritmo di controllo. Per fermare tutto, magari per un’emergenza, basta premere il pulsante SUSPEND. Infine vi è la sezione Monitor , in cui vengono visualizzati i messaggi di testo provenienti dai singoli moduli tramite la FIFO_2 (fig. 3.40). Figura 3.40 - Soplics : Monitor per la visualizzazione dei messaggi ______________________________________________________________________ Capitolo 3 : SOPLICS – Installazione ed Esecuzione di Soplics 92 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 3.5. Compilazione ed Esecuzione di Soplics Per la compilazione dei sorgenti di Soplics, basta andare nella sua cartella di installazione ( /usr/src/soplics ) e lanciare il comando make cd /usr/src/soplics make invece con il comando make clean si eliminano tutti i file oggetto generati. Per l’installazione, invece, basta lanciare make install sempre dalla cartella di soplics, questo provocherà il caricamento in memoria dei moduli necessari Alla fine se si lancia il comando lsmod si dovrebbe avere la seguente situazione: robot smartlab soplics replics pulsar a questo punto si è pronti per lanciare l’interfaccia grafica andando nella directory : /src/usr/soplics/src/scada_qt e cliccando sul file eseguibile:: splics_gui oppure da console lanciando il comando: ./splics_gui infine per scaricare i moduli dalla memoria basta scrivere: make uninstall ______________________________________________________________________ Capitolo 3 : SOPLICS –Esempio di modulo utente 93 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 3.6. Un esempio di modulo utente I moduli utente possono essere scritti con un normale editor di testi e vanno copiati nella cartella /usr/src/soplics/user_modules. La compilazione o si esegue tramite interfaccia grafica, oppure basta lanciare il comando, sempre dalla directory ../../user_modules: make SRC=nome_modulo dove nome_modulo, è il nome del modulo sorgente senza però aggiungere l’estensione .c. Di seguito viene riportato l’esempio di un semplice modulo per il controllo del nastro trasportatore. Le specifiche funzionali sono semplici, l’operatore preme il tasto START dal pannello di comando per l’inizio del ciclo , appena viene posizionato un pezzo davanti alla fotocellula 1 il nastro si mette in moto fino ad arrestarsi quando il pezzo è arrivato davanti alla fotocellula 4. A questo punto viene riconosciuto il colore del pezzo (attraverso il numero di viti rilevate dal sensore induttivo) e visualizzato sul quadro sinottico, viene poi rimosso il pezzo dalla fotocellula 4 e il ciclo inizia daccapo. Di seguito viene riportato l’SFC di controllo (fig 3.41)., mentre subito dopo è riportato il codice del modulo di controllo corrispondente, in cui risulta evidente come la struttura ricalchi l’esecuzione tipica di un PLC. Infatti c’è una sezione di inizializzazione, una per le azioni, una di valutazione delle transizioni superabili ed, infine, l’aggiornamento della condizione. ______________________________________________________________________ Capitolo 3 : SOPLICS –Esempio di modulo utente 94 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 0 Tr0 START 1 resetta il contatore viti; setta il colore neutro per il pezzo; FD1 Tr1 2 Tr2 motore nastro in avanti KMA 3 Tr3 FD4 ferma il nastro; setta colore pezzo; 4 Tr4 FD4 Figura 3.41 - SFC esempio modulo utente #define EVENT1_ON #include <splc_ctrlmod.h> static int c=0; // contatore numero viti static int fronte_di_salita(unsigned int in) { static int just1=0; if(in) { if(!(just1)) { just1=1; return 1; } else return 0; } else { just1=0; return 0; } } ______________________________________________________________________ Capitolo 3 : SOPLICS –Esempio di modulo utente 95 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ int scan_loop() { static int init=0; if(init) goto start; X(0)=1; init=1; // ----- AZIONI ------ // start: if(X(1)) { c=0; COL_PEZ=NEUTRO;} if(X(2)) { AVA=1; } if(X(4)) { AVA=0; switch(c) { case 1: COL_PEZ=VERDE; break; case 2: COL_PEZ=GRIGIO; break; case 3: COL_PEZ=BIANCO; break; default : COL_PEZ=NEUTRO; break; } } CLEAR_TR // Vengono resettate le transizioni // ----- VALUTAZIONE DELLE TRANSIZIONI SUPERABILI------------- // if(X(0) && START) TR(0)=1; if(X(1) && FD1) TR(1)=1; if(X(2) && KMA) TR(2)=1; if(X(3) && FD4) TR(3)=1; if(X(4) && !FD4) TR(4)=1; //---- AGGIORNAMENTO DELLA CONDIZIONE -----------// if(TR(0)) { X(0)=0; X(1)=1; } if(TR(1)) { X(1)=0; X(2)=1; } if(TR(2)) { X(2)=0; X(3)=1; } if(TR(3)) { X(3)=0; X(4)=1; } if(TR(4)) { X(4)=0; X(1)=1; } EVENT1=fronte_di_salita(S1); return 0; } ______________________________________________________________________ Capitolo 3 : SOPLICS –Esempio di modulo utente 96 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ static void event1_fun(int e) { c++; printk(KERN_INFO"event1_fun c=%d\n",c); } Nella parte dichiarative viene definita solo la macro EVENT1_ON, questo perché il modulo non userà né i robot e né i timer, ed usufruirà di un evento asincrono. Quest’ultimo è stato usato per il conteggio delle viti presenti sul pezzo, utili per il riconoscimento del colore. Infatti l’evento è stato legato al fronte di salita del segnale proveniente dal sensore induttivo S1. Per il riconoscimento del fronte di salita è stata usata una funzione apposita (fronte_di_salita). L’azione che deve essere eseguita al verificarsi dell’evento è contenuta nella funzione event1_fun, e consiste semplicemente nell’incrementare il contatore delle viti (costituita dalla variabile c). Nella fase 4 mediante una semplice struttura switch‐case si assegna il colore del pezzo in base al valore del contatore. Questo è un esempio molto semplice ma che aiuta a capire la potenzialità di un simile approccio al controllo. Basti pensare all’uso del contatore, che in ambito PLC ha una struttura specifica con regole rigide di funzionamento, mentre in un programma C si riduce ad una semplice variabile di incremento. Nel prossimo capitolo si analizzeranno gli algoritmi realizzati per il controllo dell’intera cella robotizzata. ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo della Cella 97 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ _______________________________________________ CAPITOLO 4 : Algoritmi di Controllo della Cella _______________________________________________ Nel seguente capitolo verranno analizzati gli algoritmi di controllo per la realizzazione di un ciclo continuo di Pallettizzazione/Depallettizzazione per la cella robotizzata. ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo della Cella – Specifiche Funzionali del Compito 98 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 4.1 Specifiche Funzionali del Compito Sul nastro sono presenti due vassoi per posizionare oggetti di plastica del tipo in figura 4.42: Figura 4.42 - Pezzi di plastica usati nella movimentazione In totale, questi oggetti, sono 12 di cui 4 di colore verde, 4 di colore grigio e 4 di colore bianco. Il colore viene riconosciuto con una codifica fatta con viti metalliche secondo la seguente corrispondenza: ¾ 1 vite ⇒ colore verde ¾ 2 viti ⇒ colore grigio ¾ 3 viti ⇒ colore bianco Il sensore induttivo, posto al centro del nastro, rileva il passaggio di un oggetto metallico e produce un impulso elettrico il cui segnale è collegato ad una delle porte di ingresso della scheda Smartlab. La rilevazione e registrazione di tale ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo della Cella – Specifiche Funzionali del Compito 99 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ segnale avviene via software all’atto della fase di lettura degli ingressi del ciclo di controllo. Il compito prevede il prelievo dei pezzi dal vassoio di sinistra del nastro, la codifica del colore e la possibilità di posizionarli sul vassoio di destra in modo predefinito, inoltre è prevista la gestione di condizioni di allarme. La modalità di posizionamento dei pezzi sul vassoio di destra può essere qualsiasi e impostata in fase di scrittura del modulo di controllo. Infatti essa viene settata tramite un semplice array i cui valori indicano proprio la posizione e il colore del pezzo sul vassoio. Nel caso specifico si è assegnato: dispo_pez[13]={'X','V','V','V','V','G','G','G','G','B','B','B','B'}; che per corrispondenza significa che: ¾ in posizione 0 non deve essere posto nessun pezzo (‘X’), infatti è la posizione neutra ¾ dalla posizione 1 alla 4 devono essere posti i pezzi di colore verde (‘V’) ¾ dalla posizione 5 alla 8 devono essere posti i pezzi di colore grigio (‘G’) ¾ dalla posizione 9 alla 12 devono essere posti i pezzi di colore bianco (‘B’) Naturalmente la disposizione può essere cambiata a piacimento e in modo immediato dall’utente. Il progetto del compito assume che nella fase iniziale i 12 pezzi siano tutti posizionati, in modo completamente casuale, sul vassoio di sinistra. La sequenza con cui questi pezzi devono essere presi dal robot può essere personalizzata, sempre tramite array, semplicemente indicando le posizioni da raggiungere nell’ordine desiderato. Una volta caricato in memoria il modulo di controllo, è richiesto l’intervento dell’operatore che deve dare inizio al ciclo premendo il pulsante START. Nella fase iniziale vengono eseguiti dei controlli, quali la presenza aria compressa nel ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo della Cella – Specifiche Funzionali del Compito 100 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ circuito di alimentazione, l’alimentazione per il pannello di controllo del nastro, l’assenza di situazioni di emergenza ed eseguiti i comandi di accensione dei motori dei due robot e di apertura delle due pinze. Successivamente si effettua una fase di pallettizzazione in cui i pezzi prelevati a sinistra dal robot 0 (quello a 6 assi), vengono posizionati sul nastro, riconosciuti in base al numero di viti metalliche e posizionati in modo predefinito sul vassoio di destra del nastro dal robot 1 (a 7 assi). Finita questa fase il funzionamento si inverte dando inizio alla depallettizzazione che riporta il sistema nella condizione iniziale. A questo punto se non è stato premuto il tasto STOP dal pannello di comando l’intero ciclo, pallettizzazione/depallettizzazione, inizia daccapo. ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo della Cella – Analisi del modulo utente di controllo 101 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 4.2 Analisi del modulo utente di controllo Prima di passare agli SFC funzionali è bene analizzare le parti principali del modulo di controllo scritto per la realizzazione del compito, il cui codice completo è riportato nell’appendice B. Partendo dalla parte dichiarativa generale possiamo notare la definizione delle seguenti macro: #define TIMER_ON #define ROBOT_ON #define EVENT1_ON #define EVENT2_ON #define ALLARM_ON #include <splc_ctrlmod.h> ossia vengono usate le strutture dati per i timer, i robot, e due dei tre eventi asincroni, inoltre viene attivata la gestione degli allarmi tramite la macro ALLARM_ON. Se si desidera disabilitare la gestione degli allarmi basta semplicemente non definire tale macro. Infine si nota l’inclusione dell’header <splc_ctrlmod.h> necessario alla corretta compilazione del modulo. Seguono altre tre macro importanti: #define BUFFER_P 3 #define COL_PEZ_TIMER 5 #define NUMERO_PEZZI 12 La prima rappresenta il buffer utilizzato per il riconoscimento del pezzo, la cui dimensione è stata fissata a 3, ossia possono stare massimo tre pezzi contemporaneamente sul nastro, pena la perdita di informazione riguardante il colore. ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo della Cella – Analisi del modulo utente di controllo 102 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ La seconda è l’assegnazione del timer per il riconoscimento del colore, la sua funzione sarà chiarita più avanti. Infine con NUMERO_PEZZI si setta il numero dei pezzi (massimo 12) usati per il ciclo di pallettizzazione/depallettizzazione.Il contatore per il numero di viti presenti sul pezzo è rappresentato dalla variabile nv, mentre per il riconoscimento del fronte di salita del segnale proveniente dal sensore induttivo è stata utilizzata la stessa funzione (fronte_di_salita) vista nell’esempio del modulo per il nastro nel capitolo precedente. All’interno della funzione principale scan_loop, vengono definite altre variabili utili per la realizzazione del ciclo di controllo. Prima di tutto si notano le matrici le cui righe rappresentano i vettori di definizione dei valori dei giunti relative alle posizioni che i due robot possono assumere all’interno della cella. Il posizionamento di un robot su un pezzo o sul nastro avviene in due fasi: la prima, veloce, di raggiungimento della posizione e la seconda, più lenta, di avvicinamento. Il posizionamento e l’avvicinamento vengono definiti sempre da degli array contenenti i valori dei giunti in modo assoluto nello spazio. Altre considerazioni possono essere fatte sull’uso delle variabili just_done per realizzare praticamente un’azione impulsiva, secondo quanto segue: if(X(5)) { …. if(!just_done) { … azione… just_done=1; } } if(X(6) { just_done=0; …… } ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo della Cella – Analisi del modulo utente di controllo 103 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ ossia nella fase X(5) il codice contenuto nel ciclo if viene eseguito una sola volta, quando si passa nella fase successiva bisogna reinizializzare la variabile just_done a zero. Tale metodo risulta efficace e utile in tutte quelle situazioni in cui l’azione non deve essere continua ma eseguita una sola volta, per esempio l’incremento di un contatore o la stampa di un messaggio di testo. La variabile init viene usata per la fase di inizializzazione del sistema, è il suo funzionamento è identico a quello di just_done. In linea con quanto detto nel paragrafo precedente, si possono individuare l’array per il posizionamento dei pezzi sul vassoio di destra (dispo_pez[13]) e quello relativo alla sequenza con cui devono essere prelevati i pezzi dal vassoio di sinistra dal robot a 6 assi : seq_pos_6a[12]={ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 } ossia si è impostato un ordine lineare dalla prima alla dodicesima posizione. Inoltre si è utilizzato un vettore (go_back[12]) per la memorizzazione dell’ordine delle posizioni raggiunte dal robot a 7 assi per il deposito dei pezzi, questo per garantire il ripristino della situazione iniziale all’atto della depallettizzazione. Ultima cosa importante da dire è il modo di utilizzo dei due eventi asincroni per il riconoscimento dei pezzi, il primo è legato al fronte di salita del segnale del sensore induttivo e il secondo ad un timer (COL_PEZ_TIMER ). Quando un pezzo passa sotto il sensore induttivo e viene rilevata la prima vite, l’evento uno si attiva incrementa il contatore e setta il timer, successive attivazioni dell’evento uno relative sempre allo stesso pezzo, incrementano solo il contatore e non hanno effetto sul timer. Allo scadere del timer è legata l’attivazione del secondo evento asincrono, che legge il valore del contatore e in base a questo decide il colore da assegnare al pezzo mettendo il suo identificativo nel buffer, fatto ciò azzera il contatore per un successivo ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo della Cella – Analisi del modulo utente di controllo 104 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ riconoscimento e resetta il timer permettendo la sua riprogrammazione. Il timer è stato fissato a 2 secondi, tempo ritenuto sufficiente per il passaggio di un pezzo intero sotto il sensore. Il file del modulo è stato denominato pal_del.c e si trova nella directory …/soplics/user_modules. ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo della Cella –Decomposizione funzionale in SFC 105 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 4.3 Decomposizione funzionale in SFC Nelle pagine successive vengono riportati gli SFC per il ciclo di pallettizzazione/depallettizzazione e quelli relativi alla gestione delle situazioni di allarme. Per la loro rappresentazione si è usati due livelli di approfondimento, uno funzionale, in cui le azioni vengono formulate con un linguaggio più descrittivo, e uno operativo in cui viene riportato il relativo codice per l’esecuzione delle azioni. Una cosa che va sottolineata è che gli SFC scritti seguono sì le regole di composizione tipiche dei PLC, ma per certi versi possono essere visti ad un livello più alto. Infatti ad ogni fase non corrisponde una o più azioni, ma corrisponde un blocco di istruzioni C che eseguono determinati compiti. L’elenco completo degli SFC è il seguente: nome GR1 GR2 GR3 GR4 M3.1 M3.2 M4.1 M4.2 GRA1 GRA2 GRA3 GRA4 GRA5 GRA6 GRA7 GRA8 descrizione liv. gerarchico Generale Nastro Robot6A Robot7A Pallet-Robot6A Depallet-Robot6A Pallet-Robot7A Depallet-Robot7A Malfunzionamento fotocellule Allarme Pinza 0 Allarme Pinza 1 Allarme Sovraccarico Termico e EMERG Allarme Compressore Allarme Riconoscimento Pezzo Allarme Robot_6A Allarme Robot_7A 1 2 2 2 2 - macrofase 2 - macrofase 2 - macrofase 2 - macrofase 1 1 1 1 1 1 1 1 ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 106 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 4.3.1 Ciclo di Pallettizzazione/Depallettizzazione GR1 : Generale Tale SFC è gerarchicamente superiore agli altri ed ha il compito di eseguire i controlli preliminari per il nastro e le pinze, di accendere i motori per i due robot, di aprire le due pinze e soprattutto sovrintende ai cambiamenti di stato degli SFC relativi al nastro e ai robot mediante sincronizzazioni. Infatti dall’analisi dello stato delle fasi è possibile individuare lo stato di avanzamento dell’intero processo. Le sincronizzazioni vengono ottenute mediante marker di fase e precisamente Fine pallettizzazione = X(44):GR3 e X(89):GR4 Fine depallettizzazione = X(58):GR3 e X(98):GR4 Alla fine delle due fasi (X(4) per la pallettizzazione e X(5) per la depallettizzazione), se non è stato premuto il pulsante di STOP, il processo riprende daccapo. ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 107 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 0 Tr0 START and STOP 1 Nastro OK Tr1 2 Controllo Pressione; PRESS_OK and timer(0)/X(2)/1sec Rilassa pinza 0; Rilassa pinza 1; PRESS_OK and timer(0)/X(2)/1sec Apri Pinza 0; Apri Pinza 1; Pressione OK e pinze aperte Tr2 3 Accensione Motori Robot; Motori Accesi Tr3 4 Fase di Pallettizzazione Fine Palettizzazione Tr4 5 Tr5 Controllo Nastro; Fase di Depallettizzazione Fine Depalettizzazione Figura 4.43 - SFC funzionale: GR1- Generale ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 108 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 0 Tr0 START and STOP 1 nastro_ok Tr1 2 Tr2 if(PRESS_OK) { load_timer(0,1*SECs); if(!timer(0)) { OPEN_PINCER_0=1; OPEN_PINCER_1=1; } else { RELAX_PINCER_0; RELAX_PINCER_1; } } PRESS_OK & SMA_0 & SMC_0 & SMA_1 & SMC_1 3 reset_timer(0); DRIVE_ON(0); DRIVE_ON(1); IS_DRIVE_ON(0) & IS_DRIVE_ON(1) Tr3 4 SYS_ST AT US=PALLET ; X(44) & X(84) Tr4 5 Tr5 if(KT & !QM & !EMERG & !FD1 & !FD2 & !FD3 & !FD4 & !S1) nastro_ok=1; SYS_ST AT US=DEPALLET ; X(58) & X(98) Figura 4.44 - SFC operativo: GR1 - Generale ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 109 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ GR2 : Nastro Il GR2 gestisce la risorsa nastro, si occupa del riconoscimento del pezzo, e si interfaccia tramite i marker di fase con: GR1, per decidere in che modalità deve operare ( pallettizzazione / depallettizzazione) GR3 , per verificare se la fase di pallettizzazione è finita GR4 , per verificare se la fase di depallettizzazione è finita 10 Fase di PALLETTIZZAZIONE Tr10 11 FD2 oppure ci sono pezzi sul nastro Tr12 12 Setta il colore Neutro per il pezzo Tr16 Tr17 KMA Tr12 17 COND1 Tr24 COND2 Setta il colore Neutro per il pezzo Pallettizzazione Tr25 FD3 oppure ci sono pezzi sul nastro Tr19 22 16 Motore avanti Fase di DEPALLETTIZZAZIONE Tr18 18 Depallettizzazione Motore Indietro KMI Tr20 19 13 Tr21 FD2 FD3 Tr13 14 20 Ferma nastro; Acquisisci colore pezzo; Nastro Fermato Tr22 Nastro Fermato Tr14 Ferma nastro 21 15 Tr15 FD3 e il robot 7a ha acquisito il colore del pezzo e deciso la posizione dove andare Tr23 FD2 COND1 : Il Robot_6a ha finito e non ci sono pezzi sul nastro COND2 : Il Robot_7a ha finito e non ci sono pezzi sul nastro Figura 4.45 - SFC funzionale : GR2 Nastro ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 110 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 10 Tr10 11 FD2 or PEZ_NAT>0 Tr12 12 Tr18 X(4) 17 COL_PEZ=NEUT RO X(44) & PEZ_NAT = 0 Tr16 AVA=1 just_done=0; X(98) & PEZ_NAT = 0 Tr24 COL_PEZ=NEUT RO X(4) Tr25 FD3 or PEZ_NAT>0 Tr19 22 16 Tr17 X(5) 18 X(5) IND=1 KMI Tr20 KMA Tr12 19 13 Tr21 FD2 FD3 Tr13 14 AVA=0; if (!just_done) { COL_PEZ=colp[0]; int i; for(i=0;i<BUFFER_P-1;i++) colp[i]=colp[i+1]; npb--; just_done=1; } 20 Tr22 IND=0 KMA & KMI 21 Tr14 KMA & KMI Tr23 FD2 15 Tr15 FD3 & X(79) Figura 4.46 - SFC operativo : GR2 Nastro ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 111 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ GR3 Robot_6A Il GR3 gestisce il robot a 6 assi, per la pallettizzazione e la depallettizzazione vengono usate due macrofasi rispettivamente M3.1 e M3.2 , ed inoltre si interfaccia con il grafo GR1 (marker di fase X(4) e X(5)). Tr30 Tr46 PALLETTIZZAZIONE 30 Inizializ. sequenza posizioni 45 31 Pezzi ancora presenti sul vassoio di sinistra Tr32 32 44 M3.1 Robot allontanato dal Nastro Tr43 Tr45 Tutti i pezzi sul vassoio di sinistra Tr60 Pezzi Finiti Tr44 DEPALLETTIZZAZIONE 46 58 Pallettizzazione M3.2 Depallettizzazione Tr61 Ci sono ancora pezzi da depositare sul vassoio di sinistra Tr47 Robot posizionato sul Nastro Tr59 Figura 4.47 - SFC funzionale : GR3 Robot_6A Tr30 Tr46 X(4) 30 seq_6a=0; 45 31 Tr32 num_pvs>0 num_pvs=0 Tr44 32 Tr60 44 M3.1 Tr43 IS_POS_OK(0) X(5) Tr45 COND1 Tr47 46 M3.2 58 X(4) Tr61 COND1 : num_pvs =NUMERO_PEZZI COND2 X(5) Tr59 IS_POS_OK(0) COND2 : num_pvs <NUMERO_PEZZI Figura 4.48 - SFC operativo : GR3 Robot_6A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 112 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ M3.1 Pallet‐Robot_6A Esso rappresenta la macrofase per eseguire la pallettizzazione ad opera del robot 0 a 6 assi. I 32 Tr32 Setta la posizione del pezzo da prendere; Posizione settata e FD2 33 Sposta il robot sul pezzo; Aggiorna posizione globale del Robot; Robot Posizionato sul Pezzo Tr33 34 Setta avvicinamento al pezzo; Aggiorna posizione globale del Robot; Avvicinamento settato e Pinza aperta Tr34 35 Avvicina il robot al pezzo; Avvicinamento eseguito e Pressione_OK Tr35 36 Tr36 Setta allontanamento dal pezzo ; timer(1)/X(36)/1sec timer(1)/X(36)/1sec Rilassa Pinza 0; Chiudi Pinza 0 Allontanamento settato e Pinza chiusa 37 Allontana il robot; Aggiorna situazione Pezzi sul Vassoio di sinistra; ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 113 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Tr37 Robot allontanato 38 Tr38 Setta la posizione per raggiungere il nastro; Posizione settata 39 Sposta il robot sul nastro; Aggiorna posizione globale del Robot; Robot Posizionato sul Nastro Tr39 40 Setta avvicinamento al nastro; Aggiorna posizione globale del Robot; Avvicinamento settato Tr40 41 Avvicina il robot al nastro; Avvicinamento eseguito e Pressione_OK Tr41 42 Tr42 Setta allontanamento dal nastro ; Aumenta Numero pezzi sul nastro; timer(1)/X(42)/1sec Rilassa Pinza 0; timer(1)/X(42)/1sec Apri Pinza 0 Allontanamento settato e Pinza aperta U 43 Allontana il robot dal nastro; Figura 4.49 - SFC funzionale : macrofase M3.1 Pallettizzazione-Robot6A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 114 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ I 32 Tr32 reset_timer(1); if(!just_done1) { p6a=seq_pos_6a[seq_6a++]; just_done1=1; } set_pos(rob6a_pos[p6a],0); is_set_pos(rob6a_pos[p6a],0) & FD2 33 MOVE_T O(0); ROB_POS(0)=IN_MOV; just_done1=0; IS_POS_OK(0) Tr33 34 set_pos(rob6a_avvic[p6a],0); ROB_POS(0)=p6a; is_set_pos(rob6a_avvic[p6a],0) & SMA_0 & SMC_0 Tr34 35 MOVE_T O(0); IS_POS_OK(0) & PRESS_OK Tr35 36 Tr36 set_pos(rob6a_pos[p6a],0); load_timer(1,1*SECs); if(!timer(1)) CLOSE_PINCER_0=1; else RELAX_PINCER_0; is_set_pos(rob6a_pos[p6a],0) & SMA_0 & SMC_0 37 MOVE_T O(0); reset_timer(1); VS_P(p6a)=NO_PEZ; if(!just_done1) { num_pvs--; just_done1=1; } ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 115 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ IS_POS_OK(0) Tr37 38 Tr38 set_pos(rob6a_pos_nat,0); just_done1=0; is_set_pos(rob6a_pos_nat,0) 39 MOVE_T O(0); ROB_POS(0)=IN_MOV; IS_POS_OK(0) Tr39 40 set_pos(rob6a_avvic_nat,0); ROB_POS(0)=SUL_NAST RO; is_set_pos(rob6a_avvic_nat,0) Tr40 41 MOVE_T O(0); IS_POS_OK(0) & PRESS_OK Tr41 42 set_pos(rob6a_pos_nat,0); if(!just_done1) { PEZ_NAT ++; just_done1=1; } load_timer(1,1*SECs); if(!timer(1)) OPEN_PINCER_0=1; else RELAX_PINCER_0 is_set_pos(rob6a_pos_nat,0) & SMA_0 & SMC_0 Tr42 U 43 MOVE_T O(0); reset_timer(1); just_done1=0; Figura 4.50 - SFC operativo : macrofase M3.1 Palletttizzazione-Robot6A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 116 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ M3.2 Depallet‐Robot_6A Esso rappresenta la macrofase per eseguire la depallettizzazione ad opera del robot 0 a 6 assi. I 46 Setta avvicinamento al nastro; Aggiorna posizione globale del Robot; Avvicinamento settato e Pinza Aperta e Nastro Fermo e FD2 Tr48 47 Avvicina il robot al nastro; Avvicinamento eseguito e Pressione OK Tr49 48 Tr50 Setta allontanamento dal nastro ; timer(1)/X(48)/1sec Rilassa Pinza 0; timer(1)/X(48)/1sec Chiudi Pinza 0 Allontanamento settato e Pinza Chiusa 49 Tr51 Allontana il robot dal nastro; Decrementa il numero di pezzi sul nastro; Estrai la posizione dove mettere il pezzo; Robot allontanato 50 Tr52 Setta la posizione dove mettere il pezzo; Posizione settata 51 Sposta il robot in posizione; Aggiorna posizione globale del Robot; ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 117 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Robot Posizionato Tr53 52 Setta avvicinamento ; Aggiorna posizione globale del Robot; Avvicinamento settato Tr54 53 Avvicina il robot alla posizione; Avvicinamento eseguito e Pressione_OK Tr55 54 Tr56 timer(1)/X(48)/1sec Setta allontanamento dalla posizione; Rilassa Pinza 0; timer(1)/X(48)/1sec Apri Pinza 0 Allontanamento settato e Pinza Aperta 55 Tr57 Allontana il robot; Aggiorna situazione Pezzi sul Vassoio di sinistra; Robot allontanato 56 Tr58 Setta la posizione per raggiungere il nastro; Posizione settata U 57 Sposta il robot sul nastro; Aggiorna posizione globale del Robot; Figura 4.51 - SFC funzionale : macrofase M3.2 Depallettizzazione Robot6A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 118 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ I 46 set_pos(rob6a_avvic_nat,0); ROB_POS(0)=SUL_NAST RO; is_set_pos(rob6a_avvic_nat,0) & (SMA_0 & SMC_0 ) & FD2 & ( KMA & KMI ) Tr48 47 MOVE_T O(0); IS_POS_OK(0) & PRESS_OK Tr49 48 Tr50 set_pos(rob6a_pos_nat,0); load_timer(1,1*SECs); if(!timer(1)) CLOSE_PINCER_0=1; else RELAX_PINCER_0; is_set_pos(rob6a_pos_nat,0) & SMA_0 & SMC_0 49 Tr51 reset_timer(1); MOVE_T O(0); if(!just_done1) { PEZ_NAT--; p6a=seq_pos_6a[seq_6a++]; just_done1=1; } IS_POS_OK(0) 50 Tr52 set_pos(rob6a_pos[p6a],0); just_done1=0; is_set_pos(rob6a_pos[p6a],0) 51 MOVE_T O(0); ROB_POS(0)=IN_MOV; ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 119 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ IS_POS_OK(0) Tr53 52 set_pos(rob6a_avvic[p6a],0); ROB_POS(0)=p6a; is_set_pos(rob6a_avvic[p6a],0) Tr54 53 MOVE_T O(0); IS_POS_OK(0) & PRESS_OK Tr55 54 set_pos(rob6a_pos[p6a],0); load_timer(1,1*SECs); if(!timer(1)) OPEN_PINCER_0=1; else RELAX_PINCER_0; } is_set_pos(rob6a_pos[p6a],0) & SMA_0 & SMC_0 Tr56 55 Tr57 MOVE_T O(0); reset_timer(1); VS_P(p6a)=NEUT RO; if(!just_done1) { num_pvs++; just_done1=1; } IS_POS_OK(0) 56 Tr58 set_pos(rob6a_pos_nat,0); just_done1=0; is_set_pos(rob6a_pos_nat,0) U 57 MOVE_T O(0); ROB_POS(0)=IN_MOV; Figura 4.52 - SFC operativo : macrofase M3.2 Depallettizzazione Robot6A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 120 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ GR4 Robot_7A Il GR4 gestisce il robot a 7 assi, per la pallettizzazione e la depallettizzazione vengono usate due macrofasi rispettivamente M4.1 e M4.2 , ed inoltre si interfaccia con il grafo GR1 (marker di fase X(4) e X(5)). Tr30 Tr86 PALLETTIZZAZIONE 70 Iniz. sequenza posizioni 85 71 Devono essere depositati ancora pezzi sul vassoio di destra Tr32 Tr84 72 Robot allontanato dal pezzo Tr85 Pezzi finiti sul vassoio di destra Tr98 84 M1.4 Tr83 Tutti i pezzi depositati sul vassoio di destra DEPALLETTIZZAZIONE Tr87 86 98 Pallettizzazione M2.4 Depallettizzazione Tr99 Pezzi ancora presenti sul vassoio di destra Robot posizionato sul Nastro Tr97 Figura 4.53 - SFC funzionale: GR4 Robot_7A Tr30 Tr86 X(4) 70 71 Tr32 COND1 72 85 COND2 IS_POS_OK(1) Tr85 Tr101 num_pvd>0 86 98 X(4) just_done2=0; just_done3=0; num_pvd=0 Tr87 Tr100 84 M1.4 Tr83 seq_7a=0; just_done2=0; just_done3=0; Tr84 X(5) M2.4 X(5) Tr99 IS_POS_OK(1) COND1 : num_pvd < NUMERO_PEZZI COND2 : num_pvd = NUMERO_PEZZI Figura 4.54 - SFC operativo: GR4 Robot_7A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 121 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ M4.1 Pallet‐Robot_7A Esso rappresenta la macrofase per eseguire la pallettizzazione ad opera del robot 1 a 7 assi. Se il robot non sa dove sistemare il pezzo, a causa di un errato riconoscimento, si ferma (hold=1) e attende l’intervento dell’operatore.. I 72 Tr72 Setta la posizione per raggiungere il nastro; Posizione settata 73 Sposta il robot sul nastro; Segnala Robot in movimento; Robot Posizionato sul Nastro Tr73 74 Setta avvicinamento al nastro; Segnala Robot sul nastro; Avvicinamento settato e Pezzo presente e Il nastro è fermo e la pinza è aperta Tr74 75 Avvicina il robot al nastro; Avvicinamento eseguito e Pressione_OK Tr75 76 Tr76 Setta allontanamento dal nastro ; timer(2)/X(76)/1sec Rilassa Pinza 1; timer(2)/X(76)/1sec Chiudi Pinza 1; Allontanamento settato e pinza chiusa 77 Allontana il robot dal nastro; Diminuisci il numero di pezzi sul nastro; ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 122 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Robot allontanato Tr77 78 Tr78 Acquisisci Colore pezzo; Trova e setta la posizione dove sistemare il pezzo; Posizione settata e il pezzo può essere sistemato 79 Sposta il robot in posizione; Segnala Robot in movimento; Robot Posizionato Tr79 80 Setta avvicinamento ; Segnala Robot in Posizione ; Avvicinamento settato Tr80 81 Avvicina il robot alla posizione; Avvicinamento eseguito e Pressione_OK Tr81 82 Setta allontanamento dalla posizione; timer(2)/X(82)/1sec Rilassa Pinza 1; timer(2)/X(82)/1sec Apri Pinza 1; Allontanamento settato e Pinza Aperta Tr82 U 83 Allontana il robot; Aggiorna la situazione dei pezzi sul vassoio di destra; Figura 4.55 - SFC funzionale: macrofase M4.1 Pallettizzazione-Robot7A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 123 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ I 72 Tr72 set_pos(rob7a_pos_nat,1); is_set_pos(rob7a_pos_nat,1) 73 MOVE_T O(1); ROB_POS(1)=IN_MOV; IS_POS_OK(1) Tr73 74 set_pos(rob7a_avvic_nat,1); ROB_POS(1)=SUL_NAST RO; is_set_pos(rob7a_avvic_nat,1) & ( SMA_1 & SMC_1) & FD3 & ( KMA & KMI ) Tr74 75 MOVE_T O(1); IS_POS_OK(1) & PRESS_OK Tr75 76 set_pos(rob7a_pos_nat,1); load_timer(2,1*SECs); if(!timer(2)) CLOSE_PINCER_1=1; else RELAX_PINCER_1; is_set_pos(rob7a_pos_nat,1) & SMA_1 & SMC_1 Tr76 77 MOVE_T O(1); reset_timer(1); if(!just_done2) { PEZ_NAT --; just_done2=1; } ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 124 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ IS_POS_OK(1) Tr77 78 Tr78 just_done2=0; if(!just_done3) { int i=1; while (dispo_pez[i]!=COL_PEZ && i<13) i++; if (i<13 && VD_P(i)==NO_PEZ) { p7a=i; col_pvd=COL_PEZ; dispo_pez[p7a]='X'; set_pos(rob7a_pos[p7a],1); } else hold=1; just_done3=1; } is_set_pos(rob7a_pos[p7a],1) & hold 79 just_done3=0; MOVE_T O(1); ROB_POS(1)=IN_MOV; IS_POS_OK(1) Tr79 80 set_pos(rob7a_avvic[p7a],1); ROB_POS(1)=p7a; is_set_pos(rob7a_avvic[p7a],1) Tr80 81 MOVE_T O(1); IS_POS_OK(1) & PRESS_OK Tr81 82 set_pos(rob7a_pos[p7a],1); load_timer(2,1*SECs); if(!timer(2)) OPEN_PINCER_1=1; else RELAX_PINCER_1; is_set_pos(rob7a_pos[p7a],1) & SMA_1 & SMC_1 Tr82 U 83 MOVE_T O(1); reset_timer(2); if(!just_done2) { num_pvd++; just_done2=1; } VD_P(p7a)=col_pvd; Figura 4.56 - SFC operativo: macrofase M4.1 Pallettizzazione Robot7A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 125 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ M4.2 Depallet‐Robot_7A Esso rappresenta la macrofase per eseguire la depallettizzazione ad opera del robot 1 a 7 assi. I 86 Tr88 Setta la posizione del pezzo da prendere; Posizione settata e FD3 87 Sposta il robot sul pezzo; Segnala robot in movimento; Robot Posizionato sul Pezzo Tr89 88 Setta avvicinamento al pezzo; Segnala robot posizionato sul pezzo; Avvicinamento settato e Pinza aperta Tr90 89 Avvicina il robot al pezzo; Avvicinamento eseguito e Pressione_OK Tr91 90 Tr92 Setta allontanamento dal pezzo ; timer(2)/X(90)/1sec Rilassa Pinza 1; timer(2)/X(90)/1sec Chiudi Pinza 1; Allontanamento settato e Pinza chiusa 91 Allontana il robot; Aggiorna la situazione dei pezzi sul vassoio di destra; ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 126 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Tr93 Robot allontanato 92 Tr94 Setta la posizione per raggiungere il nastro; Posizione settata 93 Sposta il robot sul nastro; Segnala Robot in movimento; Robot Posizionato sul Nastro Tr95 94 Setta avvicinamento al nastro; Segnala Robot sul Nastro; Avvicinamento settato Tr96 95 Avvicina il robot al nastro; Avvicinamento eseguito e Pressione_OK Tr97 96 Tr98 Setta allontanamento dal nastro ; timer(2)/X(96)/1sec Rilassa Pinza 1; timer(2)/X(96)/1sec Apri Pinza 1; Allontanamento settato e Pinza aperta U 97 Allontana il robot dal nastro; Aumenta Numero pezzi sul nastro; Figura 4.57 - SFC funzionale: macrofase M4.2 Depallettizzazione Robot7A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 127 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ I 86 Tr88 if(!just_done2) { p7a=go_back[seq_7a++]; just_done1=1; } set_pos(rob7a_pos[p7a],1); is_set_pos(rob7a_pos[p7a],1) & FD3 87 just_done2=0; MOVE_T O(1); ROB_POS(1)=IN_MOV; IS_POS_OK(1) Tr89 88 set_pos(rob7a_avvic[p7a],1); ROB_POS(1)=p7a; is_set_pos(rob7a_avvic[p7a],1) & SMA_1 & SMC_1 Tr90 89 MOVE_T O(1); IS_POS_OK(1) & PRESS_OK Tr91 90 Tr92 set_pos(rob7a_pos[p7a],1); load_timer(2,1*SECs); if(!timer(2)) CLOSE_PINCER_1=1; else RELAX_PINCER_1; is_set_pos(rob7a_pos[p7a],1) & SMA_1 & SMC_1 91 reset_timer(2); MOVE_T O(1); if(!just_done2) { dispo_pez[p7a]=VD_P(p7a); num_pvd--; just_done2=1; } VD_P(p7a)=NO_PEZ; ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Ciclo di Pallettizzazione/Depallettizzazione 128 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Tr93 IS_POS_OK(1) 92 just_done2=0; set_pos(rob7a_pos_nat,1); is_set_pos(rob7a_pos_nat,1) Tr94 93 MOVE_T O(1); ROB_POS(1)=IN_MOV; IS_POS_OK(1) Tr95 94 set_pos(rob7a_avvic_nat,1); ROB_POS(1)=SUL_NAST RO; is_set_pos(rob7a_avvic_nat,1) Tr96 95 MOVE_T O(1); IS_POS_OK(1) & PRESS_OK Tr97 96 Tr98 set_pos(rob7a_pos_nat,1); if(!just_done2) { PEZ_NAT ++; just_done2=1; } load_timer(2,1*SECs); if(!timer(2)) OPEN_PINCER_1=1; else RELAX_PINCER_1; is_set_pos(rob7a_pos_nat,1) & SMA_1 & SMC_1 U 97 MOVE_T O(1); reset_timer(2); if(!just_done2) { PEZ_NAT ++; just_done2=1; } Figura 4.58 - SFC operativo: macrofase M4.2 Depallettizzazione Robot7A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 129 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 4.3.2 Gestione Allarmi Gli allarmi possono essere classificati in: 1. Allarmi di time‐out 2. Allarmi relativi a consensi elettrici 3. Allarmi conseguenti a malfunzionamenti del programma 4. Allarmi conseguenti a stati di emergenza 1) Allarmi di time‐out Tale tipologia di allarme interviene a seguito di una qualsiasi anomalia sugli organi di presa pneumatici o sulle fotocellule del nastro trasportatore. L’allarme di time‐out deriva dall’impostazione, per ogni comando di chiusura/apertura pinza o di spostamento pezzo sul nastro, di un tempo massimo di esecuzione con esito positivo (watchdog timer). In definitiva le cause degli allarmi di time‐out possono essere: Time‐out apri/chiudi pinza 0 Time‐out apri/chiudi pinza 1 Time‐out avanzamento/arretramento nastro Il verificarsi di uno di questi allarmi è mostrato con una segnalazione a video all’operatore ed il sistema in tutti i casi, viene bloccato. Per il ripristino è richiesto l’intervento dell’operatore per la risoluzione manuale del problema e successivo riavvio del processo. ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 130 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ GRA1 Malfunzionamento Fotocellule 120 il motore del nastro è acceso Tr120 121 Tr121 Inizializza il timer; Il motore si è spento Carica il timer a 30 secondi Il motore è ancora acceso ed è scaduto il timer Tr122 Pone il sistema in stato di allarme; Segnala il malfunzionamento delle Fotocellule; Resetta il timer; 122 1 Tr123 123 Rilassa le pinze; Spegni il motore del nastro; Disabilitita tutte le fasi; Blocca i robot se in movimento; Spegni i motori dei robot; Motore del nastro spento e Motori dei robot Spenti Tr124 124 Figura 4.59 - SFC funzionale: GRA1 -Malfunzionamento Fotocellule ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 131 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 120 KMA or KMI Tr120 121 Tr121 reset_timer(10); KMA & KMI load_timer(10,30*SECs); ( KMA or KMI ) & t10/X121/20s Tr122 SYS_ST AT US=PLC_ALLARM; if(KMA) ALLARM_T YPE=T IME_OUT _AVA; else ALLARM_T YPE=T IME_OUT _IND; reset_timer(10); 122 1 Tr123 123 RELAX_PINCER_0; RELAX_PINCER_1; AVA=0; IND=0; ST ART =0; ST OP=1; int i; for(i=0;i<110;i++) X(i)=0; MOVET O_EXIT (0)=1; MOVET O_EXIT (1)=1; DRIVE_OFF(0); DRIVE_OFF(1); KMA & KMI) & IS_DRIVE_ON(0) & IS_DRIVE_ON(1) Tr124 124 Figura 4.60 - SFC operativo: GRA1 -Malfunzionamento Fotocellule ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 132 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ GRA2: Allarme Pinza 0 Inizializza il timer; 130 Impartito il comando o di apertura o di chiusura Pinza Tr130 131 Tr131 La pinza si è aperta o si è chiusa, in base al comando ricevuto Carica il timer ; il timer è scaduto Tr132 Pone il sistema in stato di allarme; Segnala il malfunzionamento della Pinza; Resetta il timer; 132 1 Tr133 133 Rilassa le pinze; Spegni il motore del nastro; Disabilitita tutte le fasi; Blocca i robot se in movimento; Spegni i motori dei robot; Motore del nastro spento e Motori dei robot Spenti Tr134 134 Figura 4.61 - SFC funzionale: GRA2 Allarme Pinza 0 ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 133 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 130 OPEN_PINCER_0 or CLOSE_PINCER_0 Tr130 131 Tr131 reset_timer(11); load_timer(11,7*SECs); OPEN_PINCER_0 & SMA_0 or CLOSE_PINCER_0 & SMC_0 !timer(11) Tr132 SYS_ST AT US=PLC_ALLARM; if(OPEN_PINCER_0) { ALLARM_T YPE=T IME_OUT _OPEN_PINCER_0; char msg[256]="La pinza sul robot a 6 assi non si è aperta. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } else { ALLARM_T YPE=T IME_OUT _CLOSE_PINCER_0; char msg[256]="La pinza sul robot a 6 assi non si è chiusa. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } reset_timer(11); 132 1 Tr133 133 RELAX_PINCER_0; RELAX_PINCER_1; AVA=0; IND=0; ST ART =0; ST OP=1; int i; for(i=0;i<110;i++) X(i)=0; MOVET O_EXIT (0)=1; MOVET O_EXIT (1)=1; DRIVE_OFF(0); DRIVE_OFF(1); KMA & KMI) & IS_DRIVE_ON(0) & IS_DRIVE_ON(1) Tr134 134 Figura 4.62 - SFC operativo: GRA2 Allarme Pinza 0 ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 134 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ GRA2: Allarme Pinza 1 Inizializza il timer; 135 Impartito il comando o di apertura o di chiusura Pinza Tr135 136 Tr136 La pinza si è aperta o si è chiusa, in base al comando ricevuto Carica il timer ; il timer è scaduto Tr137 Pone il sistema in stato di allarme; Segnala il malfunzionamento della Pinza; Resetta il timer; 137 1 Tr138 138 Rilassa le pinze; Spegni il motore del nastro; Disabilitita tutte le fasi; Blocca i robot se in movimento; Spegni i motori dei robot; Motore del nastro spento e Motori dei robot Spenti Tr139 139 Figura 4.63 - SFC funzionale: GRA3 Allarme Pinza 1 ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 135 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 135 OPEN_PINCER_1 or CLOSE_PINCER_1 Tr135 136 Tr136 reset_timer(12); load_timer(12,7*SECs); OPEN_PINCER_1 & SMA_1 or CLOSE_PINCER_1 & SMC_1 !timer(12) Tr137 SYS_ST AT US=PLC_ALLARM; if(OPEN_PINCER_1) { ALLARM_T YPE=T IME_OUT _OPEN_PINCER_1; char msg[256]="La pinza sul robot a 7 assi non si è aperta. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } else { ALLARM_T YPE=T IME_OUT _CLOSE_PINCER_1; char msg[256]="La pinza sul robot a 7 assi non si è chiusa. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } reset_timer(12); 137 1 Tr138 138 RELAX_PINCER_0; RELAX_PINCER_1; AVA=0; IND=0; ST ART =0; ST OP=1; int i; for(i=0;i<110;i++) X(i)=0; MOVET O_EXIT (0)=1; MOVET O_EXIT (1)=1; DRIVE_OFF(0); DRIVE_OFF(1); KMA & KMI) & IS_DRIVE_ON(0) & IS_DRIVE_ON(1) Tr139 139 Figura 4.64 - SFC operativo: GRA3 Allarme Pinza 1 ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 136 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 2) Allarmi relativi a consensi elettrici Tale tipologia di allarme interviene a seguito di intervento di protezioni elettriche o dal superamento di condizioni di soglia definite dal progettista. Le cause di tali allarmi nel nostro caso possono essere: Sovraccarico termico del motore del nastro ( QM) Pressione insufficiente nel circuito pneumatico Come prima, il verificarsi di uno di questi allarmi provoca una segnalazione a video all’operatore ma mentre nel primo caso si ha il blocco del sistema, nel secondo viene solo visualizzato un messaggio di avvertimento che invita a controllare se il compressore è acceso. In caso di persistente durata di pressione insufficiente sarà cura dell’operatore bloccare il sistema. Per il ripristino è richiesto l’intervento manuale dell’operatore per la risoluzione del problema (sostituzione del motore da parte di un operatore oppure pressione del pulsante di ripristino termica per quanto riguarda l’allarme da sovraccarico, accensione/ o sostituzione/riparazione del compressore ) e il riavvio del sistema. C’è da dire che l’SFC che si occupa di controllare il sovraccarico, in realtà tiene sotto controllo anche il pulsante di emergenza del pannello elettrico per il nastro trasportatore, anche se tale tipologia di allarme viene trattata successivamente. ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 137 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ GRA4 Allarme sovraccarico termico ed emergenza 140 Allarme termico motore nastro oppure è stato premuto il pulsante di emergenza Tr140 Pone il sistema in stato di allarme; Segnala il ALLARME QM o EMERG; 141 Tr141 1 142 Tr142 Rilassa le pinze; Spegni il motore del nastro; Disabilitita tutte le fasi; Blocca i robot se in movimento; Spegni i motori dei robot; Motore del nastro spento e Motori dei robot Spenti 143 Figura 4.65 - SFC funzionale: GRA4 Allarme Sovraccarico Termico ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 138 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 140 QM or EMERG Tr140 SYS_ST AT US=PLC_ALLARM; if(!QM) { char msg[256]="Si è verificato un sovraccarico termico del motore del nastro. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } else { char msg[256]="E' stato premuto il pulsante di emergenza sul pannelo di controllo del nastro. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } 141 1 Tr141 142 RELAX_PINCER_0; RELAX_PINCER_1; AVA=0; IND=0; ST ART =0; ST OP=1; int i; for(i=0;i<110;i++) X(i)=0; MOVET O_EXIT (0)=1; MOVET O_EXIT (1)=1; DRIVE_OFF(0); DRIVE_OFF(1); KMA & KMI) & IS_DRIVE_ON(0) & IS_DRIVE_ON(1) Tr142 143 Figura 4.66 - SFC operativo: GRA4 Allarme Sovraccarico Termico ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 139 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ GRA4 Allarme Compressore Inizializza il timer; 145 Pressione insufficiente Tr145 Carica il timer; 146 Tr146 La pressione è ritornata Sufficiente Pressione ancora insufficiente e Timer scaduto Tr147 Segnala di controllore se il compressore è in funzione 147 1 Tr148 Figura 4.67 - SFC funzionale: GRA5 Allarme Compressore reset_timer(13); 145 PRESS_OK Tr145 load_timer(13,50*SECs); 146 Tr146 PRESS_OK Tr147 !PRESS_OK & !timer(13) ALLARM_T YPE=PRESS_WARNING; 147 Tr148 1 Figura 4.68 - SFC operativo: GRA5 Allarme Compressore ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 140 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 3) Allarmi conseguenti a malfunzionamenti del programma Tale tipologia di allarme interviene quando si è verificato un errore nel riconoscimento del pezzo in fase di pallettizzazione. In questo caso il colore assegnato per default è l’azzurro, che rappresenta il colore neutro, ma il robot 1 non sa dove sistemare il pezzo sul vassoio di destra e quindi il processo viene sospeso (hold=1). Per risolvere tale inconveniente, appare una finestra di pop_up che avverte dell’accaduto e chiede all’operatore dove sistemare il pezzo. A questo punto il robot sistema il pezzo nella posizione indicata dall’operatore e il ciclo riprende normalmente. ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 141 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ GRA6 Allarme Riconoscimento Pezzo Resetta allarme pezzo; 150 Il robot_7a si è bloccato non sa dove sistemare il pezzo Tr150 Segnala che vi è stato un errore nel riconoscimento pezzo; Inizializza la posizione che l'utente deve definire; 151 Tr151 1 152 Se la posizione definita è accetabile allora setta i parametri e sblocca il robot; Posizione settata Tr152 Figura 4.69 - SFC funzionale: GRA6 Allarme riconoscimento pezzo ALLARM_PEZ=0; 150 X(78) & hold Tr150 ALLARM_PEZ=1; USER_POS_PEZ=-1; 151 1 Tr151 152 Tr152 if(USER_POS_PEZ!=-1 && VD_P(USER_POS_PEZ)==NO_PEZ) { p7a=USER_POS_PEZ; col_pvd=dispo_pez[p7a]; dispo_pez[p7a]='X'; set_pos(rob7a_pos[p7a],1); hold=0; } USER_POS_PEZ!=-1 Figura 4.70 - SFC operativo: GRA6 Allarme riconoscimento pezzo ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 142 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 4) Allarmi conseguenti a stati di emergenza Tale tipologia di allarme interviene quando sono premuti i funghi a ritenuta disposti sulle unità di controllo (C3G‐9000) dei robot e sulla pulsantiera del nastro. Le cause di tali allarmi possono essere quindi: Fungo premuto o allarme su Robot 0 a 6 assi Fungo premuto o allarme su Robot 1 a 7 assi Fungo premuto sulla pulsantiera del nastro trasportatore I verificarsi di uno di questi allarmi come al solito provoca una segnalazione a video all’operatore e il blocco del sistema. Per il ripristino è richiesto l’intervento manuale dell’operatore per la risoluzione del problema riguardante i robot o il nastro e il riavvio del processo. Di seguito vengono riportati gli SFC riguardanti i robot, quello relativo al nastro è stato visto precedentemente (GRA4, fig. 4.65) ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 143 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ GRA7 Allarme Robot_6A 160 Si è verificato un errore o è stato premuto il pulsante di STOP Tr160 Pone il sistema in stato di allarme; Segnala il tipo di errore che si è verificato; 161 1 Tr161 162 Rilassa le pinze; Spegni il motore del nastro; Disabilitita tutte le fasi; Blocca i robot se in movimento; Spegni i motori dei robot; Motore del nastro spento e Motori dei robot Spenti Tr162 163 Figura 4.71 - SFC funzionale: GRA7 Allarme Robot_6A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 144 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 160 Tr160 ALLARM_COND_0 SYS_ST AT US=PLC_ALLARM; 161 Stampa sul monitor utente relativo messaggio di errore* 1 Tr161 162 RELAX_PINCER_0; RELAX_PINCER_1; AVA=0; IND=0; ST ART =0; ST OP=1; int i; for(i=0;i<110;i++) X(i)=0; MOVET O_EXIT (0)=1; MOVET O_EXIT (1)=1; DRIVE_OFF(0); DRIVE_OFF(1); KMA & KMI) & IS_DRIVE_ON(0) & IS_DRIVE_ON(1) Tr162 163 ALLARM_COND_0: GET_ERROR(0,ERR_DRIVE_ON) or GET_ERROR(0,ERR_DRIVE_ON) or GET_ERROR(0,ERR_DRIVE_OFF) or GET_ERROR(0,ERR_GET) or GET_ERROR(0,ERR_SET) or GET_ERROR(0,ERR_GEN) or IS_STOP(0) * Stampa del messaggio di errore: if(GET _ERROR(0,ERR_DRIVE_ON)) { char msg[256]="ERRORE nell'accensione del motore del Robot a 6 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET _ERROR(0,ERR_DRIVE_OFF)) { char msg[256]="ERRORE nello spegnimento del motore del Robot a 6 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET _ERROR(0,ERR_GET )) { char msg[256]="ERRORE nel prendere i riferimenti nel ciclo di controllo di movimento del robot a 6 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET _ERROR(0,ERR_SET )) { char msg[256]="ERRORE nel settare i riferimenti nel ciclo di controllo di movimento del robot a 6 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET _ERROR(0,ERR_GEN)) { char msg[256]="ERRORE GENERALE. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(IS_ST OP(0)) { char msg[256]="E' stato premuto il pulsante si ST OP per il Robot a 6 assi. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } Figura 4.72 - SFC operativo: GRA7 Allarme Robot_6A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 145 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ GRA8 Allarme Robot_7A 165 Si è verificato un errore o è stato premuto il pulsante di STOP Tr165 Pone il sistema in stato di allarme; Segnala il tipo di errore che si è verificato; 166 1 Tr166 167 Rilassa le pinze; Spegni il motore del nastro; Disabilitita tutte le fasi; Blocca i robot se in movimento; Spegni i motori dei robot; Motore del nastro spento e Motori dei robot Spenti Tr167 168 Figura 4.73 - SFC funzionale: GRA8 Allarme Robot_7A ______________________________________________________________________ Capitolo 4 :Algoritmi di Controllo –Gestione Allarmi 146 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 165 ALLARM_COND_1 Tr165 SYS_ST AT US=PLC_ALLARM; 166 Tr166 Stampa sul monitor utente relativo messaggio di errore* 1 162 RELAX_PINCER_0; RELAX_PINCER_1; AVA=0; IND=0; ST ART =0; ST OP=1; int i; for(i=0;i<110;i++) X(i)=0; MOVET O_EXIT (0)=1; MOVET O_EXIT (1)=1; DRIVE_OFF(0); DRIVE_OFF(1); KMA & KMI) & IS_DRIVE_ON(0) & IS_DRIVE_ON(1) Tr166 163 ALLARM_COND_1: GET_ERROR(1,ERR_DRIVE_ON) or GET_ERROR(1,ERR_DRIVE_ON) or GET_ERROR(1,ERR_DRIVE_OFF) or GET_ERROR(1,ERR_GET) or GET_ERROR(1,ERR_SET) or GET_ERROR(1,ERR_GEN) or IS_STOP(1) * Stampa del messaggio di errore: if(GET _ERROR(1,ERR_DRIVE_ON)) { char msg[256]="ERRORE nell'accensione del motore del Robot a 7 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET _ERROR(1,ERR_DRIVE_OFF)) { char msg[256]="ERRORE nello spegnimento del motore del Robot a 7 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET _ERROR(1,ERR_GET )) { char msg[256]="ERRORE nel prendere i riferimenti nel ciclo di controllo di movimento del robot a 7 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET _ERROR(1,ERR_SET )) { char msg[256]="ERRORE nel settare i riferimenti nel ciclo di controllo di movimento del robot a 7 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET _ERROR(1,ERR_GEN)) { char msg[256]="ERRORE GENERALE. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(IS_ST OP(1)) { char msg[256]="E' stato premuto il pulsante si ST OP per il Robot a 7 assi. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } Figura 4.74 - SFC operativo: GRA8 Allarme Robot_7A ______________________________________________________________________ Bibliografia 147 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Bibliografia [1] Pasquale Chiacchio: PLC e automazione industriale, McGraw Hill, Milano 1996 [2] Alessandro Rubini & Jonathan Corbet: LINUX Device Drivers 2nd Edition [3] Nello Grimaldi : Manuale di Replics, versione 2.0, Napoli 2004 [4] RTAI Programming Guide 1.0 September 2000 [5] E. Bianchi, L. Dozio, P. Mantegazza.: DIAPM‐RTAI A Hard Real Time support for LINUX [6] Herman Bruyninckx : Real‐Time and Embedded Guide, 2002 [7] Comau : Guida all’uso C3G‐9000. – Messaggi di Errore Vol n° 2 ______________________________________________________________________ Appendice A – Programmi Ausiliari 148 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Appendice A : Programmi Ausiliari Sono stati sviluppati altri due piccoli programmi molto utili sia in caso di anomalie del programma di supervisione che in fase di sviluppo di un algoritmo di controllo. Il primo viene lanciato nel caso di improvvisa e indesiderata terminazione del programma che gestisce l’interfaccia grafica di supervisione della cella. In questi casi il modulo di controllo, in esecuzione nella parte real‐time, continua a girare normalmente mentre la finestra grafica si chiude e non si ha più la possibilità di interagire con il processo. In questi casi basta andare nella directory di soplics e lanciare da console: ./no_panic ↵ e scegliere dal menù testuale che appare ________ Pannello di Controllo____________ __________________________________________ 1 -> START | 3-> SUSPEND SYSTEM 2 -> STOP | 4-> SYSTEM STATUS _________________|________________________ 5-> USCITA __________________________________________ >_ l’opzione 3 che permette di sospendere il sistema e rilasciare le periferiche correttamente senza provocare danni ______________________________________________________________________ Appendice A – Programmi Ausiliari 149 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ A questo punto bisogna scaricare i moduli dalla memoria manualmente scrivendo nell’ordine : rmmod rmmod rmmod rmmod pal_del ↵ (nel caso il modulo utente caricato sia pal_del) robot ↵ smartlab ↵ soplics ↵ Adesso il sistema può ripartire nuovamente anche se è consigliabile un riavvio del computer. Tale inconveniente si è verificato spesso nella fase di sviluppo, adesso il software gira correttamente con una soddisfacente stabilità e affidabilità. Il secondo programma invece, può risultare utile in fase di sviluppo di un algoritmo di controllo. Infatti permette di monitorare l’evoluzione dell’SFC mostrando quale fase è attiva. Esso si lancia sempre da console, andando nella directory di soplics e lanciando il programma: ./sfc_monitor ↵ viene richiesto di inserire la fase iniziale e quella finale dell’algoritmo di controllo che si deve monitorare. Naturalmente lanciando il programma da più console diverse è possibile tenere sotto controllo l’evoluzione di più algoritmi contemporaneamente e quindi di avere una precisa indicazione dell’evoluzione dell’intero sistema. ______________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 150 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Appendice B : Codice sorgente del modulo utente pal_del // *************************************************************************************************************************** // * PAL-DEL // * // * Modulo utente per SOPLICS per il controllo della cella robotizzata del laboratorio PRISMA, // * esecuzione di un ciclo di Pallettizzazione/Depallettizazione // * // * // * Autore : Pasquale Di Lorenzo // * // ************************************************************************************************************************** #define TIMER_ON #define ROBOT_ON #define EVENT1_ON #define EVENT2_ON #define ALLARM_ON #include <splc_ctrlmod.h> #define BUFFER_P 3 // buffer contenente gli identificativi del colore dei pezzi presenti sul nastro #define COL_PEZ_TIMER 5 #define NUMERO_PEZZI 12 static int nv; static char colp[BUFFER_P]; static int npb; extern int splc_print(char*,int); // timer per rilevamento colore pezzo // numero di pezzi usati per il test // numero di viti rilevate dal sensore induttivo S1 // vettore contenente i colori dei pezzi // pezzi presenti nel buffer // Funzione esterna per la stampa di messaggi su monitor utente // Funzione di riconoscimento del fronte di salita del segnale S1 static int fronte_di_salita(unsigned int in) { static int just1=0; if(in) { if(!(just1)) { just1=1; return 1; } else return 0; } else { just1=0; return 0; } } ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 151 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ // Funzione del ciclo di controllo principale del PLC int scan_loop() { // ****************************** P A R T E D I C H I A R A T I V A ****************************************** static int init; static int p6a,p7a; static int just_done,just_done1; static int just_done2,just_done3; static int hold; static char col_pvd; static int num_pvs; static int num_pvd; // variabile di inizializzazione del ciclo // posizioni da raggiungere rispettivamente per il robot 6a e 7a // variabili per l'esecuzione univoca di un determinato blocco // variabili per l'esecuzione univoca di un determinato blocco // situazione anomala il robot non sa dove sistemare il pezzo // colore del pezzo sul vassoio di destra // numero di pezzi presenti sul vassoio di sinistra // numero di pezzi presenti sul vassoio di destra // Vettore per indicare la disposizione dei pezzi da depositare sul vassoio di destra dal robot 7a static char dispo_pez[13]={'X','V','V','V','V','G','G','G','G','B','B','B','B'}; // sequenza delle posizioni da raggiungere per il robot 6a static int seq_6a; static int seq_pos_6a[12]={ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; // Vettore contenente l'ordine con cui verranno presi i pezzi per la depallettizzazione static int seq_7a; static int go_back[12]; // ---------------- DEFINIZIONI DELLE POSIZIONI IN TERMINI DI COORDINATE DEI GIUNTI ---------------------// // --------- ROBOT 6A --------------------------------------------------------------------------------------------------------// giunti q1 q2 q3 q4 q5 q6 q7 static double rob6a_pos[13][7]={ { 0, -0, -90, -0, -0, 0, 0 }, // P0 posizione neutra { -100.94, 37.90, -118.93, 1.05, 21.22, -11.90, 0 }, // P1 { -92.42, 38.02, -118.57, 0.24, 21.42, -2.62, 0 }, // P2 { -100.07, 42.19, -109.97, 0.80, 25.88, -10.78, 0 }, // P3 { -92.22, 42.30, -109.65, 0.18, 26.05, -2.37, 0 }, // P4 { -99.28, 47.22, -99.60, 0.62, 31.22, -9.80, 0 }, // P5 { -92.05, 47.32, -99.31, 0.14, 31.37, -2.16, 0 }, // P6 { -98.65, 52.35, -89.10, 0.50, 36.58, -9.04, 0 }, // P7 { -91.91, 52.46, -88.81, 0.11, 36.72, -1.99, 0 }, // P8 { -98.12, 57.93, -77.78, 0.42, 42.33, -8.42, 0 }, // P9 { -91.79, 58.04, -77.50, 0.09, 42.46, -1.86, 0 }, // P10 { -97.66, 64.41, -64.68, 0.35, 48.92, -7.88, 0 }, // P11 { -91.69, 64.54, -64.37, 0.07, 49.08, -1.72, 0 } // P12 }; static double rob6a_avvic[13][7]={ { 0, -0, -90, -0, -0, 0 0 }, // avv_P0 posizione neutra { -100.94, 46.32, -117.70, 1.57, 14.02, -12.44, 0 }, // P1_AVV { -92.42, 46.44, -117.27, 0.35, 14.31, -2.74, 0 }, // P2_AVV { -100.07, 49.88, -108.74, 1.05, 19.43, -11.05, 0 }, // P3_AVV { -92.22, 49.98, -108.38, 0.24, 19.65, -2.43, 0 }, // P4_AVV { -99.28, 54.26, -98.36, 0.75, 25.41, -9.95, 0 }, // P5_AVV { -92.05, 54.36, -98.05, 0.17, 25.59, -2.19, 0 }, // P6_AVV { -98.65, 58.91, -87.82, 0.58, 31.30, -9.13, 0 }, // P7_AVV { -91.91, 59.02, -87.52, 0.13, 31.46, -2.01, 0 }, // P8_AVV { -98.12, 64.12, -76.41, 0.47, 37.51, -8.48, 0 }, // P9_AVV { -91.79, 64.23, -76.12, 0.10, 37.65, -1.87, 0 }, // P10_AVV { -97.66, 70.28, -63.14, 0.38, 44.59, -7.92, 0 }, // P11_AVV { -91.69, 70.42, -62.82, 0.07, 44.76, -1.74, 0 } // P12_AVV }; ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 152 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ static double rob6a_pos_nat[7]={ -47.78, 72.16, -48.80, -1.60, 57.58, 43.06, 0 }; // posizione nastro static double rob6a_avvic_nat[7]={ -47.78, 82.07, -44.27, -1.71, 52.21, 43.25, 0 }; // avv. nastro // --------- ROBOT 7A --------------------------------------------------------------------------------------------------------// giunti q1 q2 q3 q4 q5 q6 q7 static double rob7a_pos[13][7]={ { 0, -0, -90, -0, -0, 0, 1600 }, // P0 posizione neutra { 144.45, 52.43, -87.84, -0.02, 39.97, 54.19, 1383.2 }, // P1 { 144.80, 53.20, -86.29, -0.02, 40.75, 54.54, 1481.4 }, // P2 { 140.75, 53.24, -86.22, -0.05, 40.79, 50.52, 1412.5 }, // P3 { 141.14, 54.00, -84.67, -0.05, 41.57, 50.90, 1510.4 }, // P4 { 135.82, 54.51, -83.65, -0.08, 42.09, 45.62, 1457.4 }, // P5 { 136.26, 55.28, -82.09, -0.08, 42.88, 46.06, 1554.8 }, // P6 { 132.05, 55.54, -81.55, -0.11, 43.14, 41.88, 1497.1 }, // P7 { 132.53, 56.33, -79.98, -0.10, 43.94, 42.36, 1594.0 }, // P8 { 127.43, 57.05, -78.53, -0.13, 44.64, 37.28, 1551.2 }, // P9 { 127.97, 57.84, -76.94, -0.13, 45.44, 37.81, 1647.4 }, // P10 { 123.15, 58.52, -75.55, -0.15, 46.13, 33.00, 1607.9 }, // P11 { 123.74, 59.33, -73.94, -0.15, 46.94, 33.59, 1703.2 } // P12 }; static double rob7a_avvic[13][7]={ { 0, -0, -90, -0, -0, 0, 1600 }, // avv_P0 posizione neutra { 144.26, 58.51, -87.48, -0.02, 34.27, 54.00, 1389.5 }, // P1_AVV { 144.62, 59.21, -85.95, -0.02, 35.09, 54.36, 1487.7 }, // P2_AVV { 140.55, 59.25, -85.85, -0.06, 35.15, 50.32, 1418.9 }, // P3_AVV { 140.94, 59.95, -84.32, -0.06, 35.98, 50.70, 1516.8 }, // P4_AVV { 135.58, 60.42, -83.28, -0.10, 36.55, 45.39, 1464.1 }, // P5_AVV { 136.02, 61.13, -81.73, -0.09, 37.39, 45.83, 1561.5 }, // P6_AVV { 131.80, 61.39, -81.16, -0.13, 37.68, 41.64, 1504.0 }, // P7_AVV { 132.28, 62.12, -79.60, -0.12, 38.52, 42.12, 1601.0 }, // P8_AVV { 127.15, 62.80, -78.12, -0.15, 39.30, 37.01, 1558.4 }, // P9_AVV { 127.68, 63.53, -76.54, -0.15, 40.14, 37.55, 1654.6 }, // P10_AVV { 122.83, 64.19, -75.12, -0.17, 40.90, 32.72, 1615.6 }, // P11_AVV { 123.43, 64.94, -73.52, -0.17, 41.75, 33.30, 1711.0 } // P12_AVV }; static double rob7a_pos_nat[7]={ 74.49, 37.25, -115.60, -0.03, 27.51, -16.01, 1600 }; // posizione nastro static double rob7a_avvic_nat[7]={ 74.71, 53.40, -112.50, -0.05, 14.45, -15.77, 1600 }; // avv. nastro static char nastro_ok; // check sul nastro avvenuto con successo // *************************************************************************************************************************** // ************************************* C I C L O D I C O N T R O L L O ******************************************* // ------------------------------------- I N I Z I A L I Z Z A Z I O N E ---------------------------if(!init) { X(0)=1; // SFC GENERALE X(10)=1; // SFC NASTRO X(30)=1; // SFC ROBOT_6A X(70)=1; // SFC ROBOT_7A #ifdef ALLARM_ON X(120)=1; // SFC ALLARME MALFUNZIONAMENTO FOTOCELLULE X(130)=1; // SFC ALLARME PINZA 0 X(135)=1; // SFC ALLARME PINZA 1 X(140)=1; // SFC ALLARME QM e EMERG X(145)=1; // SFC ALLARME CONTROLLO COMPRESSORE X(150)=1; // SFC ALLARME ERRORE RICONOSCIMENTO PEZZO X(160)=1; // SFC ALLARME SUL ROBOT A 6 ASSI X(165)=1; // SFC ALLARME SUL ROBOT A 7 ASSI #endif COL_PEZ=NEUTRO; PEZ_NAT=0; ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 153 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ ALLARM_TYPE=0; hold=0; npb=-1; nv=0; num_pvs=NUMERO_PEZZI; num_pvd=0; p6a=0; p7a=0; seq_6a=0; seq_7a=0; nastro_ok=0; int i; for(i=1;i<13;i++) { if(i<=NUMERO_PEZZI) VS_P(i)=NEUTRO; // Vengono caricati else VS_P(i)=NO_PEZ; // i pezzi sul vassoio di sinistra VD_P(i)=NO_PEZ; } init=1; // Inizializzazione eseguita } // ****************************************** AZIONI *********************************************************** #ifdef ALLARM_ON // --------------------------------------------- A L L A R M I --------------------------------------------------------// GRA1: ALLARME MALFUNZIONAMENTO FOTOCELLULE if(X(120)) { reset_timer(10); } if(X(121)) { load_timer(10,30*SECs); } if(X(122)) { SYS_STATUS=PLC_ALLARM; if(KMA) ALLARM_TYPE=TIME_OUT_AVA; else ALLARM_TYPE=TIME_OUT_AVA; reset_timer(10); } if(X(123) || X(133) || X(138) || X(142) || X(162) || X(167)) { RELAX_PINCER_0; RELAX_PINCER_1; AVA=0; IND=0; // SPEGNE IL MOTORE DEL NASTRO START=0; STOP=1; int i; for(i=0;i<110;i++) X(i)=0; // DISABILITA TUTTE LE FASI MOVETO_EXIT(0)=1; MOVETO_EXIT(1)=1; // FERMA I ROBOT SE IN MOVIMENTO DRIVE_OFF(0); DRIVE_OFF(1); // SPEGNE I MOTORI DEI ROBOT } // GRA2: ALLARME PINZA O if(X(130)) { reset_timer(11); } if(X(131)) { load_timer(11,7*SECs); } if(X(132)) { SYS_STATUS=PLC_ALLARM; if(OPEN_PINCER_0) { ALLARM_TYPE=TIME_OUT_OPEN_PINCER_0; char msg[256]="La pinza sul robot a 6 assi non si è aperta. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } else { ALLARM_TYPE=TIME_OUT_CLOSE_PINCER_0; char msg[256]="La pinza sul robot a 6 assi non si è chiusa. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } reset_timer(11); } ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 154 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ // GRA3: ALLARME PINZA 1 if(X(135)) { reset_timer(12); } if(X(136)) { load_timer(12,7*SECs); } if(X(137)) { SYS_STATUS=PLC_ALLARM; if(OPEN_PINCER_1) { ALLARM_TYPE=TIME_OUT_OPEN_PINCER_1; char msg[256]="La pinza sul robot a 7 assi non si è aperta. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } else { ALLARM_TYPE=TIME_OUT_CLOSE_PINCER_1; char msg[256]="La pinza sul robot a 7 assi non si è chiusa. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } reset_timer(12); } // GRA4: ALLARME QM e EMERG if(X(141)) { SYS_STATUS=PLC_ALLARM; if(!QM) { char msg[256]="Si è verificato un sovraccarico termico del motore del nastro. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } else { char msg[256]="E' stato premuto il pulsante di emergenza sul pannelo di controllo del nastro. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } } //GRA5: ALLARME CONTROLLO COMPRESSORE if(X(145)) { reset_timer(13); } if(X(146)) { load_timer(13,50*SECs); } if(X(147)) { ALLARM_TYPE=PRESS_WARNING; } // GRA6: ALLARME ERRORE PEZZO if(X(150)) { ALLARM_PEZ=0; } if(X(151)) { ALLARM_PEZ=1; USER_POS_PEZ=-1; } if(X(152)) { if(USER_POS_PEZ!=-1 && VD_P(USER_POS_PEZ)==NO_PEZ) { p7a=USER_POS_PEZ; col_pvd=dispo_pez[p7a]; //viene associato il colore in riferimento alla posizione del pezzo dispo_pez[p7a]='X'; // segnala che il pezzo è stato sistemato nella posizione 'i' set_pos(rob7a_pos[p7a],1); // setta la posizione per il robot hold=0; // togle il l blocco al robot }} // GRA7: ALLARME SUL ROBOT A 6 ASSI if(X(161)) { SYS_STATUS=PLC_ALLARM; if(GET_ERROR(0,ERR_DRIVE_ON)) { char msg[256]="ERRORE nell'accensione del motore del Robot a 6 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET_ERROR(0,ERR_DRIVE_OFF)) { char msg[256]="ERRORE nello spegnimento del motore del Robot a 6 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET_ERROR(0,ERR_GET)) { char msg[256]="ERRORE nel prendere i riferimenti nel ciclo di controllo di movimento del robot a 6 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 155 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ if(GET_ERROR(0,ERR_SET)) { char msg[256]="ERRORE nel settare i riferimenti nel ciclo di controllo di movimento del robot a 6 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET_ERROR(0,ERR_GEN)) { char msg[256]="ERRORE GENERALE. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(IS_STOP(0)) { char msg[256]="E' stato premuto il pulsante si STOP per il Robot a 6 assi. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } } // GRA8: ALLARME SUL ROBOT A 7 ASSI if(X(166)) { SYS_STATUS=PLC_ALLARM; if(GET_ERROR(1,ERR_DRIVE_ON)) { char msg[256]="ERRORE nell'accensione del motore del Robot a 7 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET_ERROR(1,ERR_DRIVE_OFF)) { char msg[256]="ERRORE nello spegnimento del motore del Robot a 7 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET_ERROR(1,ERR_GET)) { char msg[256]="ERRORE nel prendere i riferimenti nel ciclo di controllo di movimento del robot a 7 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET_ERROR(1,ERR_SET)) { char msg[256]="ERRORE nel settare i riferimenti nel ciclo di controllo di movimento del robot a 7 assi. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(GET_ERROR(1,ERR_GEN)) { char msg[256]="ERRORE GENERALE. Il sistema è stato fermato "; splc_print(msg,USERMOD_CONSOLE_MSG); } if(IS_STOP(1)) { char msg[256]="E' stato premuto il pulsante si STOP per il Robot a 7 assi. Il sistema è stato fermato"; splc_print(msg,USERMOD_CONSOLE_MSG); } } #endif ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 156 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ // -------------------------------------------- G R 1 : S F C G E N E R A L E ---------------------------------------------------if(X(1)) { reset_timer(0); SYS_STATUS=PLC_READY; if(KT && QM && EMERG && !KMI && !KMA && !FD1 && !FD2 && !FD3 && !FD4 && !S1) nastro_ok=1; } if(X(2)) { if(PRESS_OK) { load_timer(0,1*SECs); if(!timer(0)) { OPEN_PINCER_0=1; OPEN_PINCER_1=1; } else { RELAX_PINCER_0; RELAX_PINCER_1; } } } if(X(3)) { reset_timer(0); DRIVE_ON(0); DRIVE_ON(1); } if(X(4)) { SYS_STATUS=PALLET; } if(X(5)) { SYS_STATUS=DEPALLET; } // --------------------------------------------- G R 2 : S F C N A S T R O -------------------------------------------------------// PALLETTIZZAZIONE if(X(11) || X(17)) { COL_PEZ=NEUTRO; } if(X(12)) { AVA=1; just_done=0;} if(X(14)) { AVA=0; if(!just_done) { if(npb>-1) { // se il buffer non è vuoto COL_PEZ=colp[0]; // viene estratto il colore dal buffer int i; for(i=0;i<BUFFER_P-1;i++) colp[i]=colp[i+1]; // la lista viene fatta avanzare npb--; // viene diminuito il numero di pezzi nel buffer } just_done=1; } } // DEPALLETTIZZAZIONE if(X(18)) { IND=1; } if(X(20)) { IND=0; } // --------------------------------------------- G R 3 : S F C R O B O T_6A ------------------------------------------------------if(X(30)) { seq_6a=0; just_done1=0; } // PALLETTIZZAZIONE if(X(32)) { reset_timer(1); if(!just_done1) { p6a=seq_pos_6a[seq_6a++]; just_done1=1; } set_pos(rob6a_pos[p6a],0); } if(X(33)) { just_done1=0; ROB_POS(0)=IN_MOV; MOVE_TO(0);} if(X(34)) { set_pos(rob6a_avvic[p6a],0); ROB_POS(0)=p6a; } if(X(35)) { MOVE_TO(0); } if(X(36)) { set_pos(rob6a_pos[p6a],0); load_timer(1,1*SECs); if(!timer(1)) CLOSE_PINCER_0=1; else RELAX_PINCER_0; } if(X(37)) { reset_timer(1); VS_P(p6a)=NO_PEZ; MOVE_TO(0); if(!just_done1) { num_pvs--; just_done1=1; } } if(X(38)) { set_pos(rob6a_pos_nat,0); just_done1=0; } if(X(39)) { MOVE_TO(0); ROB_POS(0)=IN_MOV; } if(X(40)) { set_pos(rob6a_avvic_nat,0); ROB_POS(0)=SUL_NASTRO; } if(X(41)) { MOVE_TO(0); } if(X(42)) { set_pos(rob6a_pos_nat,0); if(!just_done1) { PEZ_NAT++; just_done1=1; } load_timer(1,1*SECs); if(!timer(1)) OPEN_PINCER_0=1; ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 157 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ else RELAX_PINCER_0 } if(X(43)) { reset_timer(1); just_done1=0; MOVE_TO(0); } // DEPALLETTIZZAZIONE if(X(46)) { set_pos(rob6a_avvic_nat,0); ROB_POS(0)=SUL_NASTRO; } if(X(47)) { MOVE_TO(0); } if(X(48)) { set_pos(rob6a_pos_nat,0); load_timer(1,1*SECs); if(!timer(1)) CLOSE_PINCER_0=1; else RELAX_PINCER_0; } if(X(49)) { reset_timer(1); MOVE_TO(0); if(!just_done1) { PEZ_NAT--; p6a=seq_pos_6a[seq_6a++]; just_done1=1; } } if(X(50)) { just_done1=0; set_pos(rob6a_pos[p6a],0);} if(X(51)) { MOVE_TO(0); ROB_POS(0)=IN_MOV;} if(X(52)) { set_pos(rob6a_avvic[p6a],0); ROB_POS(0)=p6a; } if(X(53)) { MOVE_TO(0); } if(X(54)) { set_pos(rob6a_pos[p6a],0); load_timer(1,1*SECs); if(!timer(1)) OPEN_PINCER_0=1; else RELAX_PINCER_0; } if(X(55)) { reset_timer(1); MOVE_TO(0); VS_P(p6a)=NEUTRO; if(!just_done1) { num_pvs++; just_done1=1; } } if(X(56)) { just_done1=0; set_pos(rob6a_pos_nat,0); } if(X(57)) { MOVE_TO(0); ROB_POS(0)=IN_MOV; } // --------------------------------------------- G R 4 : S F C R O B O T_7A ------------------------------------------------------if(X(70)) { seq_7a=0; } // PALLETTIZZAZIONE if(X(71) || X(85)) { just_done2=0; just_done3=0; } if(X(72)) { set_pos(rob7a_pos_nat,1); } if(X(73)) { MOVE_TO(1); ROB_POS(1)=IN_MOV; } if(X(74)) { set_pos(rob7a_avvic_nat,1); ROB_POS(1)=SUL_NASTRO; } if(X(75)) { MOVE_TO(1);} if(X(76)) { set_pos(rob7a_pos_nat,1); load_timer(2,1*SECs); if(!timer(2)) CLOSE_PINCER_1=1; else RELAX_PINCER_1; } if(X(77)) { MOVE_TO(1); reset_timer(2); if(!just_done2) { PEZ_NAT--; just_done2=1; } } if(X(78)) { just_done2=0; if(!just_done3) { int i=1; // ricerca la prima posizione utile sul vassoio di destra per il pezzo di colore specficato while (dispo_pez[i]!=COL_PEZ && i<13) i++; if (i<13 && VD_P(i)==NO_PEZ) { // posizione disponibile p7a=i; // Posizione sul vassoio di destra col_pvd=COL_PEZ; // Colore del pezzo da depositare sul vassoio di destra dispo_pez[p7a]='X'; // segnala che il pezzo è stato sistemato nella posizione 'i' set_pos(rob7a_pos[p7a],1); } else hold=1; // il pezzo non può essere depositato si aspetta l'intevento dell'utente just_done3=1; } ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 158 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ } if(X(79)) { just_done3=0; MOVE_TO(1); ROB_POS(1)=IN_MOV; } if(X(80)) { set_pos(rob7a_avvic[p7a],1); ROB_POS(1)=p7a;} if(X(81)) { MOVE_TO(1);} if(X(82)) { set_pos(rob7a_pos[p7a],1); load_timer(2,1*SECs); if(!timer(2)) OPEN_PINCER_1=1; else RELAX_PINCER_1; } if(X(83)) { reset_timer(2); MOVE_TO(1); if(!just_done2) { num_pvd++; go_back[seq_7a++]=p7a; // viene memorizzato la sequenza per la depallettizzazione just_done2=1; } VD_P(p7a)=col_pvd; } // DEPALLETTIZZAZIONE if(X(86)) { if(!just_done2) { p7a=go_back[seq_7a++]; just_done2=1; } set_pos(rob7a_pos[p7a],1); } if(X(87)) { just_done2=0; MOVE_TO(1); ROB_POS(1)=IN_MOV; } if(X(88)) { set_pos(rob7a_avvic[p7a],1); ROB_POS(1)=p7a; } if(X(89)) { MOVE_TO(1); } if(X(90)) { set_pos(rob7a_pos[p7a],1); load_timer(2,1*SECs); if(!timer(2)) CLOSE_PINCER_1=1; else RELAX_PINCER_1; } if(X(91)) { reset_timer(2); MOVE_TO(1); if(!just_done2) { dispo_pez[p7a]=VD_P(p7a); num_pvd--; just_done2=1; } VD_P(p7a)=NO_PEZ; } if(X(92)) { just_done2=0; set_pos(rob7a_pos_nat,1); } if(X(93)) { MOVE_TO(1); ROB_POS(1)=IN_MOV; } if(X(94)) { set_pos(rob7a_avvic_nat,1); ROB_POS(1)=SUL_NASTRO; } if(X(95)) { MOVE_TO(1); } if(X(96)) { set_pos(rob7a_pos_nat,1); if(!just_done2) { PEZ_NAT++; just_done2=1; } load_timer(2,1*SECs); if(!timer(2)) OPEN_PINCER_1=1; else RELAX_PINCER_1; } if(X(97)) { reset_timer(2); MOVE_TO(1); just_done2=0; } ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 159 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ // *********** V A L U T A Z I O N E D E L L E T R A N S I Z I O N I S U P E R A B I L I ****************** CLEAR_TR // Vengono resettate le transizioni #ifdef ALLARM_ON // --------------------------------------------- A L L A R M I ------------------------------------------------------------// GRA1: ALLARME MALFUNZIONAMENTO FOTOCELLULE if(X(120) && (KMA || KMI)) TR(120)=1; if(X(121) && (!KMA && !KMI)) TR(121)=1; if(X(121) && (KMA && KMI) && !timer(10)) TR(122)=1; if(X(122)) TR(123)=1; if(X(123) && (!KMA && !KMI) && !IS_DRIVE_ON(0) && !IS_DRIVE_ON(1)) TR(124)=1; // GRA2: ALLARME PINZA O if(X(130) && (OPEN_PINCER_0 || CLOSE_PINCER_0)) if(X(131) && (SMA_0 || SMC_0)) if(X(131) && !timer(11)) if(X(132)) if(X(133) && (!KMA && !KMI) && !IS_DRIVE_ON(0) && !IS_DRIVE_ON(1)) TR(130)=1; TR(131)=1; TR(132)=1; TR(133)=1; TR(134)=1; // GRA3: ALLARME PINZA 1 if(X(135) && (OPEN_PINCER_1 || CLOSE_PINCER_1)) if(X(136) && (SMA_1 || SMC_1)) if(X(136) && !timer(12)) if(X(137)) if(X(138) && (!KMA && !KMI) && !IS_DRIVE_ON(0) && !IS_DRIVE_ON(1)) TR(135)=1; TR(136)=1; TR(137)=1; TR(138)=1; TR(139)=1; // GRA4: ALLARME QM e EMERG if(X(140) && (!QM || !EMERG)) if(X(141)) if(X(142) && (!KMA && !KMI) && !IS_DRIVE_ON(0) && !IS_DRIVE_ON(1)) TR(140)=1; TR(141)=1; TR(142)=1; // GRA5: ALLARME CONTROLLO COMPRESSORE if(X(145) && !PRESS_OK) if(X(146) && PRESS_OK) if(X(146) && !PRESS_OK && !timer(13)) if(X(147)) TR(145)=1; TR(146)=1; TR(147)=1; TR(148)=1; // GRA6: ALLARME ERRORE RICONOSCIMENTO PEZZO if(X(150) && X(78) && hold) if(X(151)) if(X(152) && USER_POS_PEZ!=-1) TR(150)=1; TR(151)=1; TR(152)=1; // GRA7: ALLARME SUL ROBOT A 6 ASSI if(X(160) && ( GET_ERROR(0,ERR_DRIVE_ON) || GET_ERROR(0,ERR_DRIVE_ON) || GET_ERROR(0,ERR_DRIVE_OFF) || GET_ERROR(0,ERR_GET) || GET_ERROR(0,ERR_SET) || GET_ERROR(0,ERR_GEN) || IS_STOP(0))) if(X(161)) if(X(162) && (!KMA && !KMI) && !IS_DRIVE_ON(0) && !IS_DRIVE_ON(1)) TR(160)=1; TR(161)=1; TR(162)=1; ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 160 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ // GRA8: ALLARME SUL ROBOT A 6 ASSI if(X(165) && ( GET_ERROR(1,ERR_DRIVE_ON) || GET_ERROR(1,ERR_DRIVE_ON) || GET_ERROR(1,ERR_DRIVE_OFF) || GET_ERROR(1,ERR_GET) || GET_ERROR(1,ERR_SET) || GET_ERROR(1,ERR_GEN) || IS_STOP(1))) if(X(166)) if(X(167) && (!KMA && !KMI) && !IS_DRIVE_ON(0) && !IS_DRIVE_ON(1)) TR(165)=1; TR(166)=1; TR(167)=1; #endif // -------------------------------------------- G R 1 : S F C G E N E R A L E ---------------------------------------------------if(X(0) && START && !STOP) TR(0)=1; if(X(1) && nastro_ok) TR(1)=1; if(X(2) && PRESS_OK && SMA_0 && !SMC_0 && SMA_1 && !SMC_1) TR(2)=1; if(X(3) && IS_DRIVE_ON(0) && IS_DRIVE_ON(1)) TR(3)=1; if(X(4) && X(44) && X(84)) TR(4)=1; if(X(5) && X(58) && X(98)) TR(5)=1; // --------------------------------------------- G R 2 : S F C N A S T R O -------------------------------------------------------if(X(10) && X(4)) TR(10)=1; // Pallettizzazione if(X(10) && X(5)) TR(18)=1; // Depallettizzazione // PALLETTIZZAZIONE if(X(11) && (FD2 || PEZ_NAT>0)) TR(11)=1; if(X(12) && KMA) TR(12)=1; if(X(13) && FD3) TR(13)=1; if(X(14) && !KMA && !KMI) TR(14)=1; if(X(15) && !FD3 && X(79)) TR(15)=1; if(X(11) && X(44) && PEZ_NAT==0) TR(16)=1; // Fine Pallettizzazione if(X(16) && !X(4)) TR(17)=1; // DEPALLETTIZZAZIONE if(X(17) && (FD3 || PEZ_NAT>0)) TR(19)=1; if(X(18) && KMI) TR(20)=1; if(X(19) && FD2) TR(21)=1; if(X(20) && !KMA && !KMI) TR(22)=1; if(X(21) && !FD2) TR(23)=1; if(X(17) && (X(98) && PEZ_NAT==0)) TR(24)=1; // Fine Depallettizzazione if(X(22) && !X(5)) TR(25)=1; // --------------------------------------------- G R 3 : S F C R O B O T_6A ------------------------------------------------------if(X(30) && X(4)) TR(30)=1; if(X(30) && X(5)) TR(46)=1; // PALLETTIZZAZIONE if(X(31) && num_pvs>0) TR(31)=1; if(X(32) && is_set_pos(rob6a_pos[p6a],0) && !FD2) TR(32)=1; if(X(33) && IS_POS_OK(0)) TR(33)=1; if(X(34) && is_set_pos(rob6a_avvic[p6a],0) && SMA_0 && !SMC_0) TR(34)=1; if(X(35) && IS_POS_OK(0) && PRESS_OK) TR(35)=1; if(X(36) && is_set_pos(rob6a_pos[p6a],0) && !SMA_0 && SMC_0) TR(36)=1; if(X(37) && IS_POS_OK(0)) TR(37)=1; if(X(38) && is_set_pos(rob6a_pos_nat,0)) TR(38)=1; if(X(39) && IS_POS_OK(0)) TR(39)=1; if(X(40) && is_set_pos(rob6a_avvic_nat,0)) TR(40)=1; if(X(41) && IS_POS_OK(0) && PRESS_OK) TR(41)=1; if(X(42) && is_set_pos(rob6a_pos_nat,0) && SMA_0 && !SMC_0) TR(42)=1; if(X(43) && IS_POS_OK(0)) TR(43)=1; if(X(31) && num_pvs==0) TR(44)=1; if(X(44) && !X(4)) TR(45)=1; ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 161 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ // DEPALLETTIZZAZIONE if(X(45) && num_pvs<NUMERO_PEZZI) TR(47)=1; if(X(46) && is_set_pos(rob6a_avvic_nat,0) && FD2 && (SMA_0 && !SMC_0) && (!KMA && !KMI)) TR(48)=1; if(X(47) && IS_POS_OK(0) && PRESS_OK) TR(49)=1; if(X(48) && is_set_pos(rob6a_pos_nat,0) && !SMA_0 && SMC_0) TR(50)=1; if(X(49) && IS_POS_OK(0)) TR(51)=1; if(X(50) && is_set_pos(rob6a_pos[p6a],0)) TR(52)=1; if(X(51) && IS_POS_OK(0)) TR(53)=1; if(X(52) && is_set_pos(rob6a_avvic[p6a],0)) TR(54)=1; if(X(53) && IS_POS_OK(0) && PRESS_OK) TR(55)=1; if(X(54) && is_set_pos(rob6a_pos[p6a],0) && SMA_0 && !SMC_0) TR(56)=1; if(X(55) && IS_POS_OK(0)) TR(57)=1; if(X(56) && is_set_pos(rob6a_pos_nat,0)) TR(58)=1; if(X(57) && IS_POS_OK(0)) TR(59)=1; if(X(45) && num_pvs==NUMERO_PEZZI) TR(60)=1; if(X(58) && !X(5)) TR(61)=1; // --------------------------------------------- G R 4 : S F C R O B O T_7A ------------------------------------------------------if(X(70) && X(4)) TR(70)=1; if(X(70) && X(5)) TR(86)=1; // PALLETTIZZAZIONE if(X(71) && num_pvd<NUMERO_PEZZI) TR(71)=1; if(X(72) && is_set_pos(rob7a_pos_nat,1)) TR(72)=1; if(X(73) && IS_POS_OK(1)) TR(73)=1; if(X(74) && is_set_pos(rob7a_avvic_nat,1) && FD3 && (SMA_1 && !SMC_1) && (!KMA && !KMI)) TR(74)=1; if(X(75) && IS_POS_OK(1) && PRESS_OK) TR(75)=1; if(X(76) && is_set_pos(rob7a_pos_nat,1) && !SMA_1 && SMC_1) TR(76)=1; if(X(77) && IS_POS_OK(1)) TR(77)=1; if(X(78) && is_set_pos(rob7a_pos[p7a],1) && !hold) TR(78)=1; if(X(79) && IS_POS_OK(1)) TR(79)=1; if(X(80) && is_set_pos(rob7a_avvic[p7a],1)) TR(80)=1; if(X(81) && IS_POS_OK(1) && PRESS_OK) TR(81)=1; if(X(82) && is_set_pos(rob7a_pos[p7a],1) && SMA_1 && !SMC_1 ) TR(82)=1; if(X(83) && IS_POS_OK(1)) TR(83)=1; if(X(71) && num_pvd==NUMERO_PEZZI) TR(84)=1; if(X(84) && !X(4)) TR(85)=1; // DEPALLETTIZZAZIONE if(X(85) && num_pvd>0) if(X(86) && is_set_pos(rob7a_pos[p7a],1) && !FD3) if(X(87) && IS_POS_OK(1)) if(X(88) && is_set_pos(rob7a_avvic[p7a],1) && SMA_1 && !SMC_1) if(X(89) && IS_POS_OK(1) && PRESS_OK) if(X(90) && is_set_pos(rob7a_pos[p7a],1) && !SMA_1 && SMC_1) if(X(91) && IS_POS_OK(1)) if(X(92) && is_set_pos(rob7a_pos_nat,1)) if(X(93) && IS_POS_OK(1)) if(X(94) && is_set_pos(rob7a_avvic_nat,1)) if(X(95) && IS_POS_OK(1) && PRESS_OK) if(X(96) && is_set_pos(rob7a_pos_nat,1) && SMA_1 && !SMC_1) if(X(97) && IS_POS_OK(1)) if(X(85) && num_pvd==0) if(X(98) && !X(5)) TR(87)=1; TR(88)=1; TR(89)=1; TR(90)=1; TR(91)=1; TR(92)=1; TR(93)=1; TR(94)=1; TR(95)=1; TR(96)=1; TR(97)=1; TR(98)=1; TR(99)=1; TR(100)=1; TR(101)=1; ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 162 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ // ****************** A G G I O R N A M E N T O D E L L A C O N D I Z I O N E ******************************** #ifdef ALLARM_ON // --------------------------------------------- A L L A R M I ------------------------------------------------------------// GRA1: ALLARME MALFUNZIONAMENTO FOTOCELLULE if(TR(120)) { X(120)=0; X(121)=1; } if(TR(121)) { X(121)=0; X(120)=1; } if(TR(122)) { X(121)=0; X(122)=1; } if(TR(123)) { X(122)=0; X(123)=1; } if(TR(124)) { X(123)=0; X(124)=1; } // GRA2: ALLARME PINZA O if(TR(130)) { X(130)=0; X(131)=1; } if(TR(131)) { X(131)=0; X(130)=1; } if(TR(132)) { X(131)=0; X(132)=1; } if(TR(133)) { X(132)=0; X(133)=1; } if(TR(133)) { X(133)=0; X(134)=1; } // GRA3: ALLARME PINZA 1 if(TR(135)) { X(135)=0; X(136)=1; } if(TR(136)) { X(136)=0; X(135)=1; } if(TR(137)) { X(136)=0; X(137)=1; } if(TR(138)) { X(137)=0; X(138)=1; } if(TR(139)) { X(138)=0; X(139)=1; } // GRA4: ALLARME QM e EMERG if(TR(140)) { X(140)=0; X(141)=1; } if(TR(141)) { X(141)=0; X(142)=1; } if(TR(142)) { X(142)=0; X(143)=1; } // GRA5: ALLARME CONTROLLO COMPRESSORE if(TR(145)) { X(145)=0; X(146)=1; } if(TR(146)) { X(146)=0; X(145)=1; } if(TR(147)) { X(146)=0; X(147)=1; } if(TR(148)) { X(147)=0; X(145)=1; } // GRA6: ALLARME ERRORE RICONOSCIMENTO PEZZO if(TR(150)) { X(150)=0; X(151)=1; } if(TR(151)) { X(151)=0; X(152)=1; } if(TR(152)) { X(152)=0; X(150)=1; } // GRA7: ALLARME SUL ROBOT A 6 ASSI if(TR(160)) { X(160)=0; X(161)=1; } if(TR(161)) { X(161)=0; X(162)=1; } if(TR(162)) { X(162)=0; X(163)=1; } // GRA8: ALLARME SUL ROBOT A 7 ASSI if(TR(165)) { X(165)=0; X(166)=1; } if(TR(166)) { X(166)=0; X(167)=1; } if(TR(167)) { X(167)=0; X(168)=1; } #endif // -------------------------------------------- G R 1 : S F C G E N E R A L E ---------------------------------------------------if(TR(0)) { X(0)=0; X(1)=1; } if(TR(1)) { X(1)=0; X(2)=1; } if(TR(2)) { X(2)=0; X(3)=1; } if(TR(3)) { X(3)=0; X(4)=1; } if(TR(4)) { X(4)=0; X(5)=1; } if(TR(5)) { X(5)=0; X(0)=1; } ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 163 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ // --------------------------------------------- G R 2 : S F C N A S T R O ---------------------------------------------------------// PALLETTIZZAZIONE if(TR(10)) { X(10)=0; X(11)=1; } if(TR(11)) { X(11)=0; X(12)=1; } if(TR(12)) { X(12)=0; X(13)=1; } if(TR(13)) { X(13)=0; X(14)=1; } if(TR(14)) { X(14)=0; X(15)=1; } if(TR(15)) { X(15)=0; X(11)=1; } if(TR(16)) { X(11)=0; X(16)=1; } if(TR(17)) { X(16)=0; X(10)=1; } // DEPALLETTIZZAZIONE if(TR(18)) { X(10)=0; X(17)=1; } if(TR(19)) { X(17)=0; X(18)=1; } if(TR(20)) { X(18)=0; X(19)=1; } if(TR(21)) { X(19)=0; X(20)=1; } if(TR(22)) { X(20)=0; X(21)=1; } if(TR(23)) { X(21)=0; X(17)=1; } if(TR(24)) { X(17)=0; X(22)=1; } if(TR(25)) { X(22)=0; X(10)=1; } // --------------------------------------------- G R 3 : S F C R O B O T_6A ------------------------------------------------------// PALLETTIZZAZIONE if(TR(30)) { X(30)=0; X(31)=1; } if(TR(31)) { X(31)=0; X(32)=1; } if(TR(32)) { X(32)=0; X(33)=1; } if(TR(33)) { X(33)=0; X(34)=1; } if(TR(34)) { X(34)=0; X(35)=1; } if(TR(35)) { X(35)=0; X(36)=1; } if(TR(36)) { X(36)=0; X(37)=1; } if(TR(37)) { X(37)=0; X(38)=1; } if(TR(38)) { X(38)=0; X(39)=1; } if(TR(39)) { X(39)=0; X(40)=1; } if(TR(40)) { X(40)=0; X(41)=1; } if(TR(41)) { X(41)=0; X(42)=1; } if(TR(42)) { X(42)=0; X(43)=1; } if(TR(43)) { X(43)=0; X(31)=1; } if(TR(44)) { X(31)=0; X(44)=1; } if(TR(45)) { X(44)=0; X(30)=1; } // DEPALLETTIZZAZIONE if(TR(46)) { X(30)=0; X(45)=1; } if(TR(47)) { X(45)=0; X(46)=1; } if(TR(48)) { X(46)=0; X(47)=1; } if(TR(49)) { X(47)=0; X(48)=1; } if(TR(50)) { X(48)=0; X(49)=1; } if(TR(51)) { X(49)=0; X(50)=1; } if(TR(52)) { X(50)=0; X(51)=1; } if(TR(53)) { X(51)=0; X(52)=1; } if(TR(54)) { X(52)=0; X(53)=1; } if(TR(55)) { X(53)=0; X(54)=1; } if(TR(56)) { X(54)=0; X(55)=1; } if(TR(57)) { X(55)=0; X(56)=1; } if(TR(58)) { X(56)=0; X(57)=1; } if(TR(59)) { X(57)=0; X(45)=1; } if(TR(60)) { X(45)=0; X(58)=1; } if(TR(61)) { X(58)=0; X(30)=1; } ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 164 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ // --------------------------------------------- G R 4 : S F C R O B O T_7A ------------------------------------------------------// PALLETTIZZAZIONE if(TR(70)) { X(70)=0; X(71)=1; } if(TR(71)) { X(71)=0; X(72)=1; } if(TR(72)) { X(72)=0; X(73)=1; } if(TR(73)) { X(73)=0; X(74)=1; } if(TR(74)) { X(74)=0; X(75)=1; } if(TR(75)) { X(75)=0; X(76)=1; } if(TR(76)) { X(76)=0; X(77)=1; } if(TR(77)) { X(77)=0; X(78)=1; } if(TR(78)) { X(78)=0; X(79)=1; } if(TR(79)) { X(79)=0; X(80)=1; } if(TR(80)) { X(80)=0; X(81)=1; } if(TR(81)) { X(81)=0; X(82)=1; } if(TR(82)) { X(82)=0; X(83)=1; } if(TR(83)) { X(83)=0; X(71)=1; } if(TR(84)) { X(71)=0; X(84)=1; } if(TR(85)) { X(84)=0; X(70)=1; } // DEPALLETTIZZAZIONE if(TR(86)) { X(70)=0; X(85)=1; } if(TR(87)) { X(85)=0; X(86)=1; } if(TR(88)) { X(86)=0; X(87)=1; } if(TR(89)) { X(87)=0; X(88)=1; } if(TR(90)) { X(88)=0; X(89)=1; } if(TR(91)) { X(89)=0; X(90)=1; } if(TR(92)) { X(90)=0; X(91)=1; } if(TR(93)) { X(91)=0; X(92)=1; } if(TR(94)) { X(92)=0; X(93)=1; } if(TR(95)) { X(93)=0; X(94)=1; } if(TR(96)) { X(94)=0; X(95)=1; } if(TR(97)) { X(95)=0; X(96)=1; } if(TR(98)) { X(96)=0; X(97)=1; } if(TR(99)) { X(97)=0; X(85)=1; } if(TR(100)) { X(85)=0; X(98)=1; } if(TR(101)) { X(98)=0; X(70)=1; } // ****************************** F I N E C I C L O D I C O N T R O L L O **************************************** // *************************************************************************************************************************** // ***************************************** E V E N T I A S I N C R O N I ********************************************** if(X(4)) { // PALLETTIZZAZIONE // abilita gli eventi asincroni EVENT1=fronte_di_salita(S1); EVENT2=(!timer(COL_PEZ_TIMER)); } else if(X(5)) { // DEPALLETTIZZAZIONE // disabilita gli eventi asincroni EVENT1=0; EVENT2=0; } return 0; } ___________________________________________________________________________ Appendice B – Codice sorgente del modulo pal_del 165 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ // Funzione per l'evento asincrono EVENT1 (sensore induttivo) static void event1_fun(int e) { load_timer(COL_PEZ_TIMER ,2*SECs); nv++; } // Funzione per l'evento asincrono EVENT2 (riconoscimento colore e inserimento nel buffer) static void event2_fun(int e) { // Viene inserito il colore del pezzo rilevato in coda nel buffer switch(nv) { case 1: colp[++npb]=VERDE; break; case 2: colp[++npb]=GRIGIO; break; case 3: colp[++npb]=BIANCO; break; default : colp[++npb]=NEUTRO; break; } // Viene resettato il timer e nv per il riconoscimento colore del prossimo pezzo reset_timer(COL_PEZ_TIMER); nv=0; } ___________________________________________________________________________