Vai al contenuto
PLC Forum


Generatore di Rampa per posizionatore


LoSa

Messaggi consigliati

Buongiorno,

In una libreria che sto sviluppando devo fare un posizionatore che mi posizioni un asse mosso tramite un inverter V/f comandato tramite EtherCat, mi sorgono due problemi il primo è come andare a creare le rampe di accelerazione e decelerazione del trapezio della velocità in relazione alla posizione di start del moto, che può essere variabile a seconda di dove si trova il mio asse, e alla posizione di stop del moto, ma più che altro non so la procedura da eseguire per i calcoli, scusate la mia ignoranza ma è la prima voltan che mi occupo di posizionamenti. Il secondo problema è relativo al fatto che volevo andare poi ad usare lo stesso posizionatore per una funzione di inseguimento del profilo, dove al posizionatore non interessi se ha chiuso la posizione ma che possa andare subito alla quota che ha in ingresso. Questo per far si di avere un solo posizionatore che gestisca entrambe le modalità di lavoro, la prima quella descritta nel primo problema la seconda senza che il posizionatore chiuda effettivamente le posizioni possa prenderne altre ed andare verso la successiva posizione che invio al posizionatore. Personalmente veiterei di chiamare ed instanziare più blocchi una volta che questo finisce.

Ringrazio in anticipo per le risposte,

Lorenzo

Link al commento
Condividi su altri siti


Cominciamo ad affrontare il problema della rampa.

Prima questione.

Bisogna cono scere 2 parametri: velocità massima di lavoro e pendenza della rampa.

Tanto per facilitare ipotizziamo di avere un'accelerazione 4ms2 ed una velocità massima di traslazione apri a 2ms. Quindi la rampa di accelerazione durerà 0.5"; in questo tempo, secondo l'equazione s = 1/2**a*t2 l'asse percorre 0.5m.

Per semplificare le cose poniamo che l'accelerazione positiva sia eguale a quella negativa, quindi lo spazio percorsodurante le fasi di accelerazione sarà pari ad 1m.

La prima verifica da fare è la quota da raggiungere è maggiore, uguale o minore dello spazio di accelerazione?

  1. Quota maggiore dello spazio di accelerazione, si esegue il classico profilo a trapezio
  2. Quota eguale allo spazio di accelerazione; si esegue un profilo a triangolo isoscele con vertice alla massima velocità
  3. Quota minore dello spazio di accelerazione, si esegue sempre un profilo a triangolo isoscele ma con vertice a velocità inferiore.

In effetti lo spazio di decelerazione non è una rampa completa perchè si percorre un ultimo segmento a velocità lenta.

 

Come calcolare in pratica la rampa?

Questo dipende dalla "macchina" che usi.

Tanto per fare un esempio.

Ipotizzaziomo che la velocità massima equivalga ad un riferimento di 10000 quantizzabile in 10000 punti.

Per generare una rampa di 0.5" devi avere un clock ben preciso. Se, ad esempio, il clock minimo disponibile fosse pari a 5ms dovresti incrementare il tuo riferimento di velocità di 100 ad ogni clock; in pratica avresti 100 gradini di ampiezza pari ad 1/100 della velocità massima.

 

Io, in casi di posizionamento generico usavo un metodo, che illustro nel dettaglio nelmio tutorial sulle regolazioni (sezione didattica, sottosezione elettrotecnica).

In pratica ipotizzo di avere un encoder virtuale la cui risoluzione sia identica all'encoder reale dell'asse.

A questo punto se la velocità massima corrispende ad x impulsi al secondo, 50000 p.e., eanche la quota da raggiungere corriposnderà ad n impulsi.

Creo un contatore virtuale che vado ad incrementare ad ogni clock. Ad esempio se il clock fosse sempre pari a 5 ms, ad ogni clock incremento il contatore virtuale di 250; confronto il contatore virtuale con il contatore reale. La differenza sarà il riferimento di velocità. Il contatore virtuale si incrementa sino al raggiungimento del valore di quota. Inizialmente la differeza tra quota reale e virtuale cresce, aumentando anche il riferimento di velocità. raggiunta la velocità prevista la differenza rimane costante; raggiunta la quota il contatore virtuale non si incrementa, mentre si incrementa quello reale, diminuendo il differenziale tra i 2, quindi la velocità comincia a decrescere, sino a quando i 2 contatori coincideranno.

In questo modo si generano 2 rampe eguali, corrispondenti alla massima accelerazione consentita dal sistema.

Link al commento
Condividi su altri siti

Innanzitutto che unità programmabile usi, secondo puoi crearti le rampe di accelerazione con istruzioni apposite oppure fai incrementare la variabile che ti definisce la rampa tramite una scansione a tempo fisso o un interrupt a tempo fisso, terzo in genere esistono istruzioni apposite atte alla generazione degli impulsi a frequenza variabile che fanno si che tu possa generare un certo numero di impulsi, raggiungere la frequenza definita e raggiungerla con una rampa di impulsi che la stessa unità programmabile genera in automatico e generare alla fine la rampa di decelerazione e fermarsi, quest'ultima ipotesi però necessiterebbe che tu dovessi comandare l'asse a treno d'impulsi però mi sembra non sia la tua ipotesi

Link al commento
Condividi su altri siti

Ringrazio entrambi entrambi per le due risposte, come unità programmabile, generalmente uso un PC con Codesys, con Runtime RTE, ovvero Real Time, la configurazione del PC su cui sto testando la libreria è un I3-4005u, dual core 1.7GHz, 4GB di RAM DDR3 e un SSD da 64GB, che per il tipo di applicazioni che sviluppiamo risulta più che sufficiente, il protocollo gira su una LAN 10/100/1000. Comuqnue volevo evitare di usare funzioni già  confezionate solo per un discorso di portabilità della libreria, proprio perchè sto sviluppando una vera e propria  libreria di funzioni la mia intenzione era quella di passare i dati relativi all'HW sottoforma ddi parametri della funzione, in questo modo dovrei avere una libreria che posso usare in un tutta una serie di programmi che dovrò andare a sviluppare per macchina ancora in fase di progetto, comuqnue su molte applicazioni che ho già sviluppato si va su tempi ciclo dell'ordine del centinaio di us.

Passando al discorso della Rampa, ringrazio per la spiegazione Livio ho già letto le dispense relative alla generazione della rampa, che sono stateb utlissime, solo che non riesco ad aprire i file di progetto che sono in appendice, ma poco male. Se ho capito bene per generare una rampa, "basta" generare una serie dei scalini, con un clock impostato e degli incrementi relativamente piccoli, in base all'inclinazione che voglio dare alla rampa, a questo punto chiedo, secondo voi non è possibile normalizzare l'equazione della retta che genera la rampa in forma y=mx dove m sarà > 0 per la fase di accelerazione o minore di zero per la decelerazione? Sarebbe possibile trovarsi m in funzione delle posizioni delle quali mi trovo realmente con il mio asse? In questo modo avrei un sistema che gestisce tutto da se e lo sviluppoi di un qualsiasi posizionatore si tramuterebbe in una sermplice configurazione di funzioni, vedi il discorso dell'inseguemento del profilo farei un semplice "lanciatore di quote" a questo posizionatore.

Quello che vorrei capire è come si dovrebbe comportare la funzione quando mi trovo nei momenti peggiori della generazione della rampa, ovvero quando per muovermi mi trovo già in fase di decelerazione, non so se devo partire impostando la velocità alta o se prima far fare un pezzettino di acelerazione e subito dopo la decelerazione del sistema, tipo triangolo isoscele oppure scaleno, a seconda della durata dei miei due segmenti di accelerazione e decelerazione. 

Ringrazio in anticipo delle risposte,

Lorenzo

Link al commento
Condividi su altri siti

29 minuti fa, LoSa ha scritto:

l'equazione della retta che genera la rampa in forma y=mx dove m sarà > 0 per la fase di accelerazione o minore di zero per la decelerazione?

 

Si è possibile, ma alla fine devi sempre arrivare al differenziale di velocità nel differenziale di tempo.

Qualsiasi sitema usi hai sempre come limite il minimo differenziale di tempo ed il minimo differenziale di riferimento di velocità.

31 minuti fa, LoSa ha scritto:

Quello che vorrei capire è come

 

Rivedi la casistica che ti ho esposto all'inizio.

Devi sempre avere il traguardo di metà quota ed il traguardo di inizio decelerazione per rampa totale; se questo traguardo cade prima della metà della quota, raggiunta la metà quota inizi la decelerazioen.

Link al commento
Condividi su altri siti

Roberto Gioachin

Come dice Livio devi calcolare gli incrementi e decrementi nell'unità di tempo, di seguito un esempio di come si può fare questo calcolo.

 

Naturalmente dovrai stabilire tu con altre funzioni quando accelerare e quando decelerare.

2020-04-16_09h08_37.png

Link al commento
Condividi su altri siti

Vi ringrazio per le ripsoste, molto utili entrambe, penso di aver capito come poter andare avanti nello sviluppo della libreria. In pratica il codjiuce della rampa diventerà una cosa del tipo

rd:=rPosAct-rPosTarget;

if rd > rSacc + rSdec then

   Riseco a generare e ad arrivare alla velocità massima e genero una serie di  scalini in base al tempo di scansione del PLC

if rPosAct < rPosTarget - rPosDec then

Saturero la velocità qui

rOUTSpeed:=rOUTSpeed + rINC;

else

genero isoscele secondo la stessa formula ma fermandomi sul quando rPosAct=rPosTarger-rPosDec

Sopra manca l'inizio della decelerazione,

Appena finisco di creare il codice lo posto...

Ringrazio entrambi per la disponibilità

Link al commento
Condividi su altri siti

Roberto Gioachin
56 minuti fa, LoSa ha scritto:

Scusate il doppio post ma ho messo invio per sbaglio

 

Puoi sempre modificare il messaggio dopo averlo inviato, hai un apposito pulsante "Modifica". Poi premi "Salva"

Modificato: da Roberto Gioachin
Link al commento
Condividi su altri siti

Ho riunito i 2 messaggi.

Sino a circa 10 minuti dopo aver inviato il messaggio puoi modificarlo con il tasto "modifica". Oltre il tempo limite non si può modificare per evitare che modifiche troppo tardive causino confusioni con le risposte.

Link al commento
Condividi su altri siti

Ho finito di scrivere il codice, alla fine genero la rampa semplicemente in base alla posizione di dove si trova l'asse rispetto al target:

il codice è diviso in due funzioni:

Questa per la preparazione dei dati per il segnale di velocità

rPosStart:=rPosAct;
//Calcolo le pendenze delle rampe
IF rPosAcc <> 0 THEN
    rPendenzaSalita:=rVMax/rPosAcc;
END_IF
IF rPosDec <> 0 THEN
    rPendenzaDiscesa:=-rVMax/rPosDec;//Coefficiente angolare della retta discendente deve essere negativo
END_IF
//Scalo le accelerazioni a secionda della velocità di posizionamento scelta dall'utente
rPosAccScalata:=(rVelPositioning / rVMax) * rPosAcc;
rPosDecScalata:=(rVelPositioning / rVMax) * rPosDec;
rDistanza:=rPosAccScalata + rPosDec;//Calcolo lo spazio minimo di movimento per completare acc e dec
rDelta:=ABS(rPosAct - rPosTarget); //Calcolo il delta fra il target e la mia posizione
//Controllo la direzione dove devo andare con l'asse per il segno della velocità
IF rDelta > rDistanza THEN
    //Ho il percorso abbastyanza lungo da poter fare tutto il trapezio
    IF rPosStart <= rPosTarget THEN //Vado a salire
        rPosFineAcc:=rPosStart + rPosAccScalata;
        rPosInizioDec:=rPosTarget - rPosDecScalata;
    ELSE
        //Vado a scendere
        rPosFineAcc:=rPosStart - rPosAccScalata;
        rPosInizioDec:=rPosTarget + rPosDecScalata;
    END_IF
ELSE
    //Percoroso corto
    rRapp:=rDelta/rDistanza;
    IF rPosTarget >= rPosStart THEN //Vado a salire
        rPosFineAcc:=rPosStart + (rPosAccScalata * rRapp);
        rPosInizioDec:=rPosFineAcc;
    ELSE
        //Vado a scendere
        rPosFineAcc:=rPosStart - (rPosAccScalata * rRapp);
        rPosInizioDec:=rPosFineAcc;
    END_IF    
END_IF

Questa per la generazione effettiva del segnale di velocità

IF rPosAct <= rPosTarget THEN
    //Vado a salire
    IF rPosAct > rPosTarget THEN
        //Ho superato il target
        rVelTrapezio:= - rVMin;
    ELSIF rPosAct < rPosFineAcc THEN
        //Sono in salita
        rDist:=rPosAct - rPosStart;
        rVelTrapezio:=rPendenzaSalita * rDist;
        IF rVelTrapezio <=rVMin THEN//Spiano
            rVelTrapezio:= rVMin;
        END_IF
    ELSIF rPosAct >= rPosInizioDec THEN
        //Sono in discesa
        rDist:=rPosTarget - rPosAct;
        rVelTrapezio:= - (rPendenzaDiscesa * rDist);
        IF rVelTrapezio <= rVMin THEN
            rVelTrapezio:=rVMin;
        END_IF     
    ELSE //Sono nel mezzo
        rVelTrapezio:=rVMax;
    END_IF  
    IF rVelTrapezio > 0 AND rVelTrapezio < rVMin THEN
        rVelTrapezio:=rVMin;
    END_IF
ELSE
    //Vado a scendere
    IF rPosAct < rPosTarget THEN
        rVelTrapezio:=rVMin; //Ho superato e torno indietro
    ELSIF rPosAct > rPosFineAcc THEN//Rampa Salita
        rDist:=ABS(rPosAct - rPosStart);
        rVelTrapezio:= - rPendenzaSalita * rDist;
        IF rVelTrapezio >= -rVMin THEN
            rVelTrapezio:= -rVMin;
        END_IF
    ELSIF rPosAct <= rPosInizioDec THEN //Rampa Discesa
        rDist:=ABS(rPosTarget - rPosAct);
        rVelTrapezio:=rPendenzaDiscesa * rDist;
        IF rVelTrapezio >= -rVMin THEN
            rVelTrapezio:= -rVMin;
        END_IF
    ELSE //Sono nel mezzo del moto
        rVelTrapezio:=-rVelPositioning;        
    END_IF
    IF rVelTrapezio < 0 AND rVelTrapezio > (0 - rVMin) THEN//Questo perchè rVmin viene impostata sempre >0
        rVelTrapezio:= - rVMin;    
    END_IF
END_IF

La funzione è già debuggata e funzionante, comunque i commenti migliorativi sono sempre ben accetti

Ciao,

Lorenzo

 

 

 

 

 

Link al commento
Condividi su altri siti

Roberto Gioachin
5 ore fa, LoSa ha scritto:

rPosAccScalata:=(rVelPositioning / rVMax) * rPosAcc;

Prima di eseguire una divisione devi verificare che il divisore sia diverso da zero

Link al commento
Condividi su altri siti

Lo faccio nello stato di standby del mio asse,  controllo che i valori abbiano dei valori ammissibili, in questo modo il codice diventa più semplice da leggere, se no avresti ragione. 

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...