Ein KR6 (KR C2 V5.2.15) holt Bauteile von einem Stapel. Er fährt von oben langsam heran und wenn der Sensor das Teil erkennt (Interrupt), wird angehalten (BRAKE), angesaugt und (RESUME) wieder nach oben gefahren. Funktioniert wunderbar, denkt der Roboterprogrammierer und klopft sich auf die Schulter. Der Kunde fragt den Roboterprogrammierer, warum der Roboter "ständig" anhält und ihm dadurch kostbare Millisekunden flöten gehen. Der Roboterprogrammierer erklärt ihm: Das Anhalten kommt vom fehlenden Überschleifen in das Folgeprogramm. Der Kunde verdreht die Augen und fragt wieder: Warum hält der Roboter an? Der Roboterprogrammierer befragt das Roboterforum, ob da noch was geht.
DEF holen_B1S1( )
[...]
INTERRUPT DECL 5 WHEN diSENSOR DO saugen()
[...]
Hoehe=Stapelhoehe[1,1]
;FOLD PTP HOME CONT Vel= 100 % DEFAULT
;FOLD PTP HOME2 CONT Vel= 100 % PDAT3
;Position drueber
;FOLD PTP P1 CONT Vel= 100 % PDAT1 Tool[1]:Greifer Base[0]
Suche()
Stapelhoehe[1,1]=Hoehe
;Position drueber
;FOLD LIN P1 CONT Vel= 0.5 m/s CPDAT1 Tool[1]:Greifer Base[0]
;FOLD PTP HOME2 CONT Vel= 100 % PDAT4
;FOLD PTP HOME CONT Vel= 100 % DEFAULT
CONTINUE
IF (diTEILEKONTROLLE) THEN
ablegen()
ENDIF
CONTINUE ; Versuch den Vorlaufstopp zu verhindern (unwirksam)
END
DEF Suche( )
INTERRUPT ON 5
;Linear relativ auf Hoehe fahren
Verschiebung=$NULLFRAME
Verschiebung.Z=Hoehe-XP1.Z+20
XP2=Verschiebung:XP1
;FOLD LIN P2 CONT Vel= 1 m/s CPDAT3 Tool[1]:Greifer Base[0]
;FOLD LIN P3 Vel= 0.1 m/s CPDAT5 Tool[1]:Greifer Base[0]
WAIT SEC 0
;nichts gefunden
INTERRUPT OFF 5
Hoehe=XP3.Z
END
DEF saugen()
INTERRUPT OFF 5
BRAKE
;FOLD 1 Sauger 2 VACUUM GDAT1
Hoehe = $POS_INT.Z
LIN $POS_INT
IF NOT diTEILEKONTROLLE THEN
;FOLD SET Sauger State= OFF GDAT2
Hoehe=HoeheNull
ENDIF
WAIT SEC 0.1
RESUME
END
Alles anzeigen
Konkret geht es um den Vorlaufstopp am Ende des Programms holen_B1S1(). Laut Experten-Dokumentation erfolgt am END ein Vorlaufstopp, wenn im Programm ein Interrupt deklariert wurde:
Das Stichwort "non-global" könnte dazu verleiten, ein GLOBAL davor zu setzen, aber dann habe ich ja den Vorlaufstopp in der Deklarationszeile ("has already been declared"). (Richtig?)
CONTINUE vor dem END sieht schon ziemlich verzweifelt aus und hilft hier anscheinend nicht (siehe Code). (Sollte das funktionieren?)
Da ich keinen Vorlaufstopp möchte, müsste ich den Interrupt also weiter oben in der Programmstruktur deklarieren, also ungefähr da wo der Loop (holen-ablegen) ist. Dann funktioniert aber das RESUME so nicht mehr, denn "RESUME bricht alle laufenden Interrupt-Programme und alle laufenden Unterprogramme ab bis zu der Ebene, in der der aktuelle Interrupt deklariert wurde." Und das hätte zur Folge, dass ich dann dort die Fortsetzbewegung (vom Stapel nach oben fahren) planen müsste.
Habe ich also nur die Wahl zwischen Pest (Vorlaufstopp am Ende vom Holen-Programm) oder Cholera (Fortsetzen der Bewegung nach dem Saugen im übergeordneten Programm)? Oder fällt euch noch was ein?
Wenn ich irgendwo oben falsche Annahmen getroffen habe, korrigiert mich gerne!
Gruß,
M.