1 / 28

Simple-PLC

Simple-PLC. un linguaggio di programmazione per PLC Progetto d'esame di Linguaggi e Modelli Computazionali LS Anno Accademico 2007/2008 Autore: Emiliano Capoccia Docente: Enrico Denti. Introduzione. Un P LC ( Programmable Logic Controller) è una macchina sequenziale sincrona

lecea
Download Presentation

Simple-PLC

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Simple-PLC • un linguaggio di programmazione per PLC • Progetto d'esame di Linguaggi e Modelli Computazionali LS • Anno Accademico 2007/2008 • Autore: • Emiliano Capoccia • Docente: • Enrico Denti

  2. Introduzione • Un PLC (Programmable Logic Controller) è una macchina sequenziale sincrona • PLC : “sistema elettronico a funzionamento digitale, destinato all’uso in ambito industriale, che utilizza una memoria programmabile per l’archiviazione interna di istruzioni orientate all’utilizzazione per l’implementazione di funzioni specifiche, come quelle logiche, di sequenziamento, di temporizzazione, di conteggio e di calcolo aritmetico, e per controllare, mediante ingressi ed uscite sia digitali che analogici, vari tipi di macchine e processi” • Funzionamento ciclico, all'interno di ogni clock il PLC: • legge tutti gli ingressi • esegue il programma • aggiorna tutte le uscite

  3. Programmare un PLC... • La normativa IEC 1131-3 definisce cinque linguaggi di programmazione per i PLC, di cui tre grafici e due testuali. • Linguaggi grafici • diagramma funzionale sequenziale (SFC, Sequential Functional Chart)‏ • linguaggio a contatti (LD, Ladder Diagram)‏ • diagramma a blocchi funzionali (FBD, Function Block Diagram)‏ • Linguaggi testuali: • lista di istruzioni (IL, Instruction List)‏ • testo strutturato (ST, Structured Text)‏ • derivato dai disegni dei sistemi di controllo realizzati a relé elettormeccanici, il che lo rende facilmente accettabile a tecnici “di vecchia scuola” • si basa sui concetti di contatto e bobina ed è stato inizialmente pensato per funzioni di logica binaria • è un linguaggio di basso livello e poco strutturato, non molto adatto a sistemi complessi • è presente in tutti i PLC industriali ed è uno standard di fatto del mercato americano • http://en.wikipedia.org/wiki/Ladder_logic ----[ ]---------|--[ ]--|------( )-- X | Y | S | | |--[ ]--| Z S = X AND ( Y OR Z )‏

  4. Obiettivi e motivazioni • Obiettivi del progetto • Realizzare un linguaggio (S-plc) che permetta di descrivere un programma eseguito da una macchina automatica, in termini di sequenze, stati, transizioni, ed azioni. • Realizzare un compilatore per tale linguaggio per convertire un programma S-plc in Ladder Diagram • Motivazioni • Semplificare la scrittura di programmi per PLC, con codice più vicino al linguaggio naturale, di aumentata leggibilità e manutenibilità

  5. Requisiti funzionali • Descrizione di un automazione come insieme di sequenze (ASF) in esecuzione concorrente parallela (una Rete di Petri)‏ • Ogni sequenza è un insieme di stati fra loro variamente interconnessi. Ogni stato della sequenza ha uno o più stati destinazione; la transizione da un certo stato verso gli N stati di destinazione è condizionata al verificarsi di altrettanti N eventi distinti • Durante la permanenza in un dato stato, vengono effettuate delle azioni che realizzano la funzione desiderata

  6. Analisi del problema • L'approccio usato per la compilazione (generazione del LD) è quello derivato dalla macchina a stati: • si inizializzano gli stati iniziali di ciascuna sequenza nella scansione “first scan” • per ciascuno stato, si esprime il circuito che realizza la logica di transizione verso ogni stato di destinazione, e questo circuito pilota il latch del nuovo stato e parallelamente il reset dell'attuale, realizzando il cambio stato • per ogni stato, si riportano tutte le uscite attive durante l'attivazione dello stato stesso • La suddivisione logica in sequenze di un programma aiuta l'utente nella costruzione del programma; una volta compilato il programma, tale suddivisione logica è “persa”, il programma viene di fatto eseguito come se non ci fossero tali sequenze ma solamente un insieme di stati e transizioni simultanee

  7. Esempio • programma { sequenza main1 { • stato st1 { transita in st2 quando timer tim2 timeout && ( sensore sensore1 on && sensore sensore2 off ) || timer tim1 timeout; pistone pist1 apre, motore mot1 avanti, segnala sig1, timer tim1 12 start } • stato iniziale st2 { transita in st1 quando timer tim1 timeout && ( sensore sens3 off || sensore sens4 on ); pistone pist2 chiude interferenza tizio caio, motore mot1 stop, timer tim2 19 start • } • stato st3 { transita in st1 quando sensore pippo on; pistone pist2 apre • } } sequenza mia1 { • stato iniziale a1 { transita in a3 quando timer tim1 timeout && segnalato sig1; • } stato a2 { • transita in a3 quando ( sensore sensore2 off || sensore senst1 on || sensore senst2 on • || sensore senst3 on ) && ( sensore senst4 on || sensore senst5 off || ( sensore • senst6 on && sensore p1 on || sensore p2 on || sensore p3 on || sensore p4 off ) || • sensore senst7 off || sensore senst8 on || sensore senst9 on || • sensore senst10 on ) && ( sensore senst11 on && sensore senst12 off || sensore senst13 on ); } stato a3 { • transita in a2 quando sensore sensore2 on; • transita in a1 quando sensore sensore2 off; } } • } ASF #1 transizione da st1->st2 azioni evento composito ASF #2 transizioni multiple, assenza di azioni per uno stato

  8. Grammatica in formato EBNF • G = <VT, VN, P, S> • S :- programma{ ( Sequenza )+ } il programma è costituito da una o più sequenze (automazioni semplici)‏ ciascuna automazione semplice idealmente rappresenta un ASF a se stante, con un suo stato iniziale, un solo stato attivo in ogni istante, le sue transizioni ed uscite • Sequenza :- sequenza<ID>{ ( Stato )+ } ogni sequenza a sua volta è costituita da uno o più stati; l'id di sequenza è solo per ausilio dell'utente, non è una informazione utilizzata per generare il codice • Stato :- stato ( iniziale )? <ID>{ ( transita in<ID> quando OrEvent; )+ ( Action ( , Action )* )? uno stato può essere stato iniziale, ha una etichetta ( id ) e deve avere necessariamente una transizione verso uno stato futuro (identificato dal suo id), al verificarsi di un dato evento; può avere o meno azioni in uscita. Uno stato senza azioni in uscita è in genere usato come attesa per coordinazione con altre sequenze Le transizioni in uscita da uno stato possono essere multiple. • OrEvent :- AndEvent ( ||AndEvent )* un evento è (in questo lavoro, semanticamente) una funzione booleana- gli eventi tipici di una macchina sono lo stato alto/basso di un sensore, lo stato 1-0 di un bit di registro.. Si vuole dare all'utente la possibilità di esprimere espressioni booleane di AND e OR comunque complesse. La prima produzione di un evento è dunque una somma di prodotti (tanti termini AND sommati, ovvero posti in OR)..

  9. Grammatica in formato EBNF • AndEvent :- TerminalEvent ( &&TerminalEvent )* a sua volta una produzione di tipo AND è costituita da uno o più termini in AND fra loro. In questo modo garantiamo la priorità dall'AND sull'OR (o se volete del * sul +) quando non vengono usate parentesi • TerminalEvent :- sensore<ID> ( on | off ) | • timer <ID>timeout | • segnalato<ID> | • (OrEvent)‏ Un evento terminale infine espande in varie produzioni che semanticamente rappresentano un evento semplice (vero/falso): un sensore alto o basso, lo scadere del tempo su un timer.. Accanto alle produzioni di termini VT tuttavia, un evento terminale può espandere in un evento OR racchiuso tra parentesi, permettendo all'utente di scrivere quanti livelli di innestamento desidera. Il self-embedding è su eventoOr -> eventoAnd -> eventoTerminale -> ( eventoOr )‏ • Action :- pistone<ID> ( apre | chiude ) ( interferenza ( <ID> )+ )? | • motore<ID> ( avanti | indietro | stop ) | • segnala<ID> | • timer <ID><NUM>start Le espansioni delle azioni sono solo terminali • <ID> :- ["a"-"z","A"-"Z","_"] ( ["a"-"z","A"-"Z","_","0"-"9"] )* > • <NUM> :- ["1"-"9"] (["0"-"9"])* Per correttezza formale ho indicato in blu anche i NUM e gli ID che (tradizionalmente) costituiscono a tutti gli effetti dei terminali di un sotto-linguaggio di tipo 3 generato dalle ultime due produzioni di figura

  10. Grammatica EBNF: considerazioni non c'è ℇ-rule da S: programma vuoto non generabile self-embedding: grammatica di tipo 2 (context-free)‏ G = <VT, VN, P, S> S :- programma{ ( Sequenza )+ } Sequenza :- sequenza<ID>{ ( Stato )+ } Stato :- stato ( iniziale )? <ID>{ ( transita in<ID> quando OrEvent; )+ ( Action ( , Action )* )? } OrEvent :- AndEvent ( ||AndEvent )* AndEvent :- TerminalEvent ( &&TerminalEvent )* TerminalEvent :- sensore<ID> ( on | off ) | timer <ID>timeout | segnalato<ID> | (OrEvent)‏ Action :- pistone<ID> ( apre | chiude ) ( interferenza ( <ID> )+ )? | motore<ID> ( avanti | indietro | stop ) | segnala<ID> | timer <ID><NUM>start <ID> :- ["a"-"z","A"-"Z","_"] ( ["a"-"z","A"-"Z","_","0"-"9"] )* > <NUM> :- ( [“0”-”9”] )+ riconoscitore PDA e analisi ricorsiva discendente starter-symbols (quasi)disgiunti per ogni produzione: grammatica “sostanzialmente” LL(1)‏

  11. Grammatica EBNF: considerazioni Action opzionale nella produzione Stato: la lista di azioni per uno stato può essere vuota! ℇ -rule “implicita”, le produzioni di Stato (con e senza lista azioni) si possono vedere come: Stato :- a | aA (non-LL1)‏ Ma “sostanzialmente” LL1: Stato :- aX X :- a | ℇ non c'è ℇ-rule da S: programma vuoto non generabile, ma... G = <VT, VN, P, S> S :- programma{ ( Sequenza )+ } Sequenza :- sequenza<ID>{ ( Stato )+ } Stato :- stato ( iniziale )? <ID>{ ( transita in<ID> quando OrEvent; )+ ( Action ( , Action )* )? } OrEvent :- AndEvent ( ||AndEvent )* AndEvent :- TerminalEvent ( &&TerminalEvent )* TerminalEvent :- sensore<ID> ( on | off ) | timer <ID>timeout | segnalato<ID> | (OrEvent)‏ Action :- pistone<ID> ( apre | chiude ) ( interferenza ( <ID> )+ )? | motore<ID> ( avanti | indietro | stop ) | segnala<ID> | timer <ID><NUM>start <ID> :- ["a"-"z","A"-"Z","_"] ( ["a"-"z","A"-"Z","_","0"-"9"] )* > <NUM> :- ( [“0”-”9”] )+ In questa grammatica, le situazioni in cui c’è una produzione opzionale, sono riconducibili a delle ℇ-rules “implicite” del tipo: “X :- a | ℇ” e vengono gestite dal parser che riconosce la presenza o meno della stringa vuota (ovvero di un token terminatore come } o di uno non appartenente al sottolinguaggio generato dalla produzione in esame analogamente per la lista dei pistoni interferenti sulla produzione: Azione :- pistone …

  12. Implementazione – Strumenti utilizzati • Linguaggio impiegato: Java (jdk 1.6)‏ • Strumenti automatici: JavaCC (4.0)‏ JavaCC è stato impiegato per: • realizzare lo stub dello scanner • valutare la realizzabilita' del linguaggio complessivo, prima di intraprendere il progetto e la codifica del parser. In questo senso, JavaCC e' stato utilizzato come strumento di analisi • Ambiente di sviluppo: Eclipse (sdk 3.3.1)‏

  13. Implementazione il componente scanner utilizzato è basato su quello generato automaticamente da JavaCC adattato a livello di interfaccia per farlo cooperare con il parser e con qualche funzionalità aggiuntiva (token letti da file xml e validati da xsd piuttosto che hard-coded)‏ • riconoscimento del linguaggio • un componente con la responsabilita' di eseguire lo scanning del file di input ed identificare i singoli token del linguaggio • un componente con la responsbilita' di interpretare sintatticamente le frasi del linguaggio e costruire l'albero sintattico astratto • compilazione in LD • Pattern Visitor su APT generato APT come ADT: parser realizzato come componente dinamico, riceve un riferimento allo scanner di supporto (di cui è client) in fase di costruzione, e lo passa alle varie classi che realizzano il parsing. Durante il processo di costruzione dell'albero astratto nello scanner e' memorizzato lo stato del processo di costruzione dell'APT in termini della parte di programma residua da processare

  14. Architettura del sistema 1/4schema dei packages

  15. Architettura del sistema 2/4 interfaccia comune a tutti i nodi dell'albero produzioni multiple con meccanismo ereditarietà self-embedding rappresentato dall'associazione che chiude l'anello la visita degli oggetti contenuti viene propagata dal contenitore (passando l'istanza corrente di scanner lungo la catena)‏

  16. Architettura del sistema 3/4 astrazione TOKEN wrapper del componente generato da JavaCC funzionalità aumentata ed interfaccia adattata al sistema setTabellaToken() da file xml esterno: <tokens xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="src/main/resources/splc.xsd"> <PRGHEADER value="programma"/> <SIGNAL value="segnala"/> ... VALIDATI TRAMITE (splc.)XSD: ... <xsd:complexType name="tokeninfo"> <xsd:attribute name="value" type="xsd:string" use="required"></xsd:attribute> </xsd:complexType> <xsd:complexType name="docinfo"> <xsd:all> <xsd:element name="PRGHEADER" type="tokeninfo" minOccurs="1" maxOccurs="1"></xsd:element> <xsd:element name="SIGNAL" type="tokeninfo" minOccurs="1" maxOccurs="1"></xsd:element> ... <xsd:element name="tokens" type="docinfo"></xsd:element>

  17. Architettura del sistema 4/4 invocato prima del CodeGeneration visitor esegue vari controlli semantici: che tutti gli stati dei vari ASF siano raggiungibili, che ci sia uno stato iniziale ∀ ASF, ... necessario al generatore di codice per conoscere la “profondita” dei rami in parallelo da generare è un visitor di supporto a CodeGeneration

  18. Comportamento del sistema Macchina a stati del parser “usa”

  19. Processo di compilazione prima fase: costruzione dell'APT seconda fase: visita dell'APT costruito mediante double-dispatch

  20. Testing • Per i test è stato utilizzato il framework JUnit • Sono stati realizzati alcuni sorgenti per testare il comportamento sia dei singoli componenti, sia del compilatore nel suo complesso: • con file di ingresso validi • simulando errori di sintassi • simulando errori semantici • E' stato infine eseguito con successo un test su simulatore LADSIM3 di una automazione generata da S-plc

  21. Analisi di copertura

  22. il file di esempio iniziale... • programma { sequenza main1 { • stato st1 { transita in st2 quando timer tim2 timeout && ( sensore sensore1 on && sensore sensore2 off ) || timer tim1 timeout; pistone pist1 apre, motore mot1 avanti, segnala sig1, timer tim1 12 start } • stato iniziale st2 { transita in st1 quando timer tim1 timeout && ( sensore sens3 off || sensore sens4 on ); pistone pist2 chiude interferenza tizio caio, motore mot1 stop, timer tim2 19 start • } • stato st3 { transita in st1 quando sensore pippo on; pistone pist2 apre • } } sequenza mia1 { • stato iniziale a1 { transita in a3 quando timer tim1 timeout && segnalato sig1; • } stato a2 { • transita in a3 quando ( sensore sensore2 off || sensore senst1 on || sensore senst2 on • || sensore senst3 on ) && ( sensore senst4 on || sensore senst5 off || ( sensore • senst6 on && sensore p1 on || sensore p2 on || sensore p3 on || sensore p4 off ) || • sensore senst7 off || sensore senst8 on || sensore senst9 on || • sensore senst10 on ) && ( sensore senst11 on && sensore senst12 off || sensore senst13 on ); } stato a3 { • transita in a2 quando sensore sensore2 on; • transita in a1 quando sensore sensore2 off; } } • }

  23. ...compilato in S-plc *** INIT *** |--[FIRST SCAN]----(S)R1-----------------------------------------------------------------------------------------------| | |--(S)R4-----------------------------------------------------------------------------------------------| *** TRANSIZIONI *** |--[ ]R0----[ ]T0-------[ ]X0-----[/]X1--------(R)R0-------------------------------------------------------------------| | |---[ ]T1-------------------------| |--(S)R1-------------------------------------------------------------------| |--[ ]R1----[ ]T1-------[/]X2--------(R)R1-----------------------------------------------------------------------------| | |---[ ]X3--| |--(S)R0-----------------------------------------------------------------------------| |--[ ]R3----[ ]X4-------(R)R3------------------------------------------------------------------------------------------| | |--(S)R0------------------------------------------------------------------------------------------| |--[ ]R4----[ ]T1-----[ ]R2-------(R)R4--------------------------------------------------------------------------------| | |--(S)R5--------------------------------------------------------------------------------| |--[ ]R6------[/]X1--------[ ]X8-----------------------[ ]X19-----[/]X20--------(R)R6----------------------------------| | |---[ ]X5--| |---[/]X9-----------------| |---[ ]X21-------------| |--(S)R5----------------------------------| | |---[ ]X6--| |-----[ ]X10-----[ ]X11---| | | |---[ ]X7--| | |---[ ]X12-------------|| | | | |---[ ]X13-------------|| | | | |---[/]X14-------------|| | | |---[/]X15----------------| | | |---[ ]X16----------------| | | |---[ ]X17----------------| | | |---[ ]X18----------------| | |--[ ]R5----[ ]X1-------(R)R5------------------------------------------------------------------------------------------| | |--(S)R6------------------------------------------------------------------------------------------| |--[ ]R5----[/]X1-------(R)R5------------------------------------------------------------------------------------------| | |--(S)R4------------------------------------------------------------------------------------------| *** AZIONI *** |--[ ]R0----( )Y1------------------------------------------------------------------------------------------------------| | |--( )Y3------------------------------------------------------------------------------------------------------| | |--( )R2------------------------------------------------------------------------------------------------------| | |--(TMX T1, K 12)---------------------------------------------------------------------------------------------| |--[ ]R1----( )Y4------------------------------------------------------------------------------------------------------| | |--(TMX T0, K 19)---------------------------------------------------------------------------------------------| |--[ ]R3----( )Y5------------------------------------------------------------------------------------------------------|

  24. un programma più semplice... • programma { sequenza avanzanastro { • stato iniziale idle { • transita in marcia quando sensore pulsantestart on; • motore principale stop • } stato marcia { • transita in pezzopronto quando sensore fotocellula on; • transita in idle quando sensore pulsantestart off; • motore principale avanti • } stato pezzopronto { • transita in marcia quando sensore fotocellula off; • transita in idle quando sensore pulsantestart off; • motore principale stop • } } • }

  25. ...compilato in S-plc & con indicazione dei relè.. *** INIT *** |--[FIRST SCAN]----(S)R0-----------------------------------------------------------------------------------------------| *** TRANSIZIONI *** |--[ ]R0----[ ]X0-------(R)R0------------------------------------------------------------------------------------------| | |--(S)R1------------------------------------------------------------------------------------------| |--[ ]R1----[ ]X1-------(R)R1------------------------------------------------------------------------------------------| | |--(S)R2------------------------------------------------------------------------------------------| |--[ ]R1----[/]X0-------(R)R1------------------------------------------------------------------------------------------| | |--(S)R0------------------------------------------------------------------------------------------| |--[ ]R2----[/]X1-------(R)R2------------------------------------------------------------------------------------------| | |--(S)R1------------------------------------------------------------------------------------------| |--[ ]R2----[/]X0-------(R)R2------------------------------------------------------------------------------------------| | |--(S)R0------------------------------------------------------------------------------------------| *** AZIONI *** |--[ ]R1----( )Y1------------------------------------------------------------------------------------------------------| * TABELLA DEGLI STATI INTERNI Rele: R1 Simbolico: marcia Rele: R0 Simbolico: idle Rele: R2 Simbolico: pezzopronto * TABELLA DEGLI INGRESSI Ingresso: X1 Simbolico: fotocellula Ingresso: X0 Simbolico: pulsantestart * TABELLA DELLE USCITE Uscita: Y1 Simbolico: principaleOFF Uscita: Y0 Simbolico: principaleON

  26. .. simulato in LADSIM!

  27. Limiti e caratteristiche non supportate • Il linguaggio così come è stato definito ha meno potere espressivo del LD • Non sono definiti alcune astrazioni importanti (ad es. contatto con fronte di salita/discesa)‏ • Assume che gli attuatori siano tutti a doppio effetto comandati da servovalvole bistabili • Non ha alcuni tipi di bobine in uscita (latch S/R).. • Il coordinamento tra gli ASF paralleli può essere (molto) ampliato ricorrendo ad una grammatica più ricca piuttosto che demandare all'utente l'uso dei segnali • Sono tutte estensioni più o meno facili da implementare sulla struttura proposta (ad es. per un contatto “edged” si potrebbe scrivere un evento del tipo “..quando sensore idxx fronte di salita...” e corrispondentemente aggiornare eventi/visitors.. • Più arduo appare convincere i “soliti” utenti a non usare LD... :-)

  28. Sviluppi futuri • supporto a livello di linguaggio per eventi “particolari” (timer azionato all'interno dello stato per cui costituisce la condizione di uscita)‏ • aumento dell'espressività • inserimento dei blocchi di sequenze sotto “master control relay” • implementare tutte le caratteristiche non supportate della slide precedente..

More Related