Dynamische CNC-Bahn programmieren
In diesem Beispiel wird gezeigt, wie eine CNC-Bahn direkt in der Applikation zur Laufzeit erzeugt werden kann, also nicht aus einem CNC-Programmobjekt oder einer Datei mit G-Code gespeist wird. Wenn ein solches herkömmliches CNC-Programm übersetzt wird, werden die Bahndaten in einer Datenstruktur mit Datentyp SMC_CNC_Data gespeichert Diese internen Daten werden dann abhängig vom Übersetzungsmodus (SMC_CNC_REF oder SMC_OutQueue) in spezielle globale Datenstrukturen übersetzt.
Beim Übersetzungsmodus SMC_CNC_REF werden die Daten in einem Array von Elementen des Typs SMC_GEOINFO gespeichert. Üblicherweise wird das Array im Applikationscode an die Funktionsbaustein-Instanz SMC_NCDecoder übergeben. Zur Laufzeit werden die Daten dort decodiert und in eine globale Datenstruktur des Typs SMC_OUTQUEUE ablegt. Anschließend können Bahnvorverarbeitungsbausteine aufgerufen werden.
Beim Übersetzungsmodus SMC_OutQueue wird direkt eine globale Datenstruktur (SMC_OUTQUEUE) erzeugt, die im Applikationscode an den Interpolator (FB-Instanz SMC_Interpolator) übergeben wird. Der Funktionsbaustein SMC_NCDecoder wird nicht aufgerufen.
Beim Übersetzungsmodus FILE werden die Daten in einer Datei gespeichert. Die Daten sind dabei als Array von Elementen des Typs SMC_GEOINFO abgelegt und entsprechen den Daten, die beim Übersetzungsmodus SMC_CNC_REF erzeugt werden.
Statt die CNC-Bahn grafisch zu programmieren, können Sie einen Applikationscode programmieren, der zur Laufzeit eine Datenstruktur des Typs SMC_OUTQUEUE instanziert und ihr Werte zuweist. Sie programmieren eine CNC-Bahn, die zur Laufzeit dynamisch erzeugt wird. Die Datenstruktur können Sie dann an weitere Funktionsbaustein-Instanzen (beispielsweise an Bahnvorverarbeitungsbausteine oder an den Funktionsbaustein SMC_Interpolator) übergeben.
Info
Im Installationsverzeichnis von CODESYS finden Sie das Beispielprojekt CNCDynamicPath. Das Beispielprojekt wurde aus dem Projekt CNConline entwickelt. Es enthält statt der grafisch programmierten Bahn Example das Programm Path. Es erzeugt dynamisch eine Datenstruktur mit Typ SMC_OUTQUEUE.
Deklaration:
Deklarieren Sie eine Datenstruktur des Typs SMC_OUTQUEUE. Die Datenstruktur enthält die CNC-Bahndaten und wird dynamisch gefüllt.
Beispiel: QUEUE
Allozieren Sie Speicher für die Bahn mit der gewünschten Anzahl an SMC_GEOINFO-Elementen.
Beispiel: BUF
Deklarieren Sie eine Variable des Typs SMC_GEOINFO mit einem Initialschritt.
Beispiel: GEO
Implementierung:
Ein Arrayelement des Datenyps SMC_GEOINFO entspricht einem Bahnelement im CNC-Code. Für jedes Element müssen folgende Schritte durchgeführt werden, um es der SMC_OUTQUEUE hinzuzufügen:"
Jedes Arrayelement verfügt über eine Startposition, die der Endposition des vorhergehenden Arrayelements entspricht.
Beispiel: GEO.piStartPos.dX := 0; oder GEO.piStartPos := GEO.piDestPos;
Bestimmen Sie für jedes Arrayelement einen Bewegungstyp.
Beispiel: GEO.iMoveType := CCLW; oderGEO.iMoveType := LIN;
Setzen Sie die Parameter des Bewegungstypen. Das ist nicht bei allen Bewegungstypen erforderlich.
Beispiel: Bei einem Kreisbogen (Bewegungstyp CCLW) ist das Setzen der folgenden Positionen erforderlich: geoinfo_A[i].dP1 := 200; geoinfo_A[i].dP2 := 100; geoinfo_A[i].dP3 := 50; geoinfo_A[i].dT1 := 0; geoinfo_A[i].dT2 := 90;
Fügen Sie die Berechnung der Endposition ein.
SMC_CalcEndPnt(ADR(GEO));
Fügen Sie die Berechnung der Länge des Objekts ein.
SMC_CalcLengthGeo(ADR(GEO));
Speichern Sie das Objekt in QUEUE :
SMC_AppendObj(POQ:=ADR(QUEUE), PGI:=ADR(GEO));
Wenn die Bahn vollständig erstellt ist, muss die Endmarke gesetzt werden:
QUEUE-bEndOfList = TRUE;
Info
Wenn anschließend ein Bahnvorverarbeitungsbaustein aufgerufen wird, ist es erforderlich das Anfangs- oder Endbit für InternMark zu setzen.
Beispiel
CNC-Bahn mit 2 Bahnelementen
In diesem Beispiel sind die Arrays mit den x/y-Positionen nicht definiert. Wenn das wie beschrieben ein Beispiel mit zwei Bahnelementen sein soll, müssten diese Arrays je zwei Elemente haben. Aus dem Beispielprojekt entlehnt also z.B.:
xp:ARRAY[1..2] OF REAL:= [100,50]; yp:ARRAY[1..2] OF REAL:= [0,100];
PROGRAM Path
VAR
iState : INT;
QUEUE : SMC_OUTQUEUE;
BUF : ARRAY[0..49] OF SMC_GEOINFO;
// Memory allocation
GEO : SMC_GEOINFO:=(dT1:=0, dT2:=1, dToolRadius:=0, dVel:=100, dVel_End:=100, dAccel:=200, dDecel:=500, iObj_Nr:=0);
// Initial path element
n : INT := 0;
QUEUE.nSize := SIZEOF(BUF);
END_VAR
CASE iState OF
0:
QUEUE.pbyBuffer := ADR(BUF[0]);
// Initialize QUEUE
SMC_SetQueueCapacity(ADR(QUEUE), SIZEOF(BUF));
iState := iState + 1;
1:
// Fill QUEUE
WHILE NOT QUEUE.bFull DO
// When QUEUE is full, wait until it has been processed by the following FBs
n := n + 1;
GEO.iSourceLine_No := n;
GEO.piStartPos := GEO.piDestPos;
// Copying last destination
GEO.iMoveType := LIN;
// Generating linear movement
GEO.iObjNo := GEO.iObjNo + 1;
// Calculating number
GEO.piDestPos.dX := xp[n];
// Generatint position
GEO.piDestPos.dY := yp[n];
SMC_CalcLengthGeo(pg := ADR(GEO));
// Calculating length of object with the help of the standard function
SMC_AppendObj(poq:=ADR(QUEUE), pgi:=ADR(GEO));
// Appending object to QUEUE
IF n = SIZEOF(xp)/SIZEOF(xp[1]) THEN
// All target positions processed
QUEUE.bEndOfList := TRUE;
n := 0;
iState := 2;
EXIT;
END_IF
END_WHILE
2:
//Done
;
END_CASE
CheckVel(bExecute:=TRUE , poqDataIn:=ADR(queue)); // Preprocessing
Hinweis
Wenn die Datenstruktur SMC_OUTQUEUE mit SMC_GEOINFO-Daten gefüllt und das Datenstrukturelement bFULL = TRUE gesetzt wurde, dann ist ein weiteres Zuweisen von SMC_GEOINFO-Daten nicht ratsam. Denn in diesem Fall wird zur Laufzeit die Erstellung der Bahnunterbrochen, bis das erste Element der SMC_OUTQUEUE-Datenstruktur im Interpolator verarbeitet ist. Erst dann wird ein weiteres Element angehängt.
Vermeiden Sie diese Unterbrechung, indem Sie ausreichend großen Speicher allozieren. Siehe Variable BUF.
Siehe auch