%%% VERSION:1 LANGUAGE:ENGLISH %%% MODULE Maschine_1 !****************************************************************** !* * !* A B B - E N T N A H M E R O B O T E R * !* ===================================== * !* * !* Station : Maschine 1 * !* Subjekt : Entnahme für 99 Typen * !* Roboter Nr. : IRB 64-10478 * !* Softwarestand: OS 3.2 * !* * !* Author : M. Majewski / O. Salo * !* Company : IRS Industrie-Roboter-Service GmbH * !* Adress : Vogelsbergstr. 199 * !* 63679 Schotten * !* Version : 1.0 * !* Created : 16. September 2002 * !* Modified : 28. Mai 2004 M.Majewski Greifertyp 1 * !* * !****************************************************************** !********************************************************** !* Variablendefinition * !********************************************************** !Merker, Schutztüranforderung VAR bool bSchutztuer:=FALSE; !Merker, Taktende VAR bool bTaktende:=FALSE; !Merker, Roboter zur Homepos PERS bool bIRBzurHome:=FALSE; !Merker, aktueller Teiltyp PERS num nTyp:=1; PERS string stTyp:="1"; !Merker, aktueller Greifertyp PERS num nGreiferTyp:=1; PERS string stGreiferTyp:="1"; !Variablen für Zyklus Greiferreinigung VAR num nZaehlerReinigen:=0; CONST num nAnzahlReinigen:=2; !Wartezeit, bis eine Meldung auf dem PG ausgegeben wird PERS num ntTimeOut:=3; !Tauchzeiten im Schlichtebecken CONST num ntTauchen:=4.5; !Abtropfzeit über Schlichtebecken CONST num nt1Abtropfen:=4; CONST num nt2Abtropfen:=3; !Merker, Funktionstaste VAR num nFkey; !Abbruch bei falscher Auswahl CONST errnum erAnwahl:=95; CONST errnum erOfenFrei:=95; !* Teilgewicht für 99 Typen * PERS loaddata loAlleTypen{99}:=[[24,[0,0,400],[1,0,0,0],0,0,0],[20,[0,0,400],[1 PERS loaddata loKerntyp:=[24,[0,0,400],[1,0,0,0],0,0,0]; !********************************************************** !* Prozedur haupt() * !* * !* Diese Routine steuert den kompletten Zyklus des * !* Roboters. * !* * !* Date: Version: Programmer: Reason: * !* 16.09.2002 1.0 O.Salo created * !* 28.05.2004 2.0 M.Majewski modify * !********************************************************** PROC haupt() !Hauptprogramm, Neustart von hier
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
%%% VERSION:1 LANGUAGE:ENGLISH%%%
MODULE Maschine_1 !****************************************************************** !* * !* A B B - E N T N A H M E R O B O T E R * !* ===================================== * !* * !* Station : Maschine 1 * !* Subjekt : Entnahme für 99 Typen * !* Roboter Nr. : IRB 64-10478 * !* Softwarestand: OS 3.2 * !* * !* Author : M. Majewski / O. Salo * !* Company : IRS Industrie-Roboter-Service GmbH * !* Adress : Vogelsbergstr. 199 * !* 63679 Schotten * !* Version : 1.0 * !* Created : 16. September 2002 * !* Modified : 28. Mai 2004 M.Majewski Greifertyp 1 * !* * !****************************************************************** !********************************************************** !* Variablendefinition * !********************************************************** !Merker, Schutztüranforderung VAR bool bSchutztuer:=FALSE; !Merker, Taktende VAR bool bTaktende:=FALSE; !Merker, Roboter zur Homepos PERS bool bIRBzurHome:=FALSE; !Merker, aktueller Teiltyp PERS num nTyp:=1; PERS string stTyp:="1"; !Merker, aktueller Greifertyp PERS num nGreiferTyp:=1; PERS string stGreiferTyp:="1"; !Variablen für Zyklus Greiferreinigung VAR num nZaehlerReinigen:=0; CONST num nAnzahlReinigen:=2; !Wartezeit, bis eine Meldung auf dem PG ausgegeben wird PERS num ntTimeOut:=3; !Tauchzeiten im Schlichtebecken CONST num ntTauchen:=4.5; !Abtropfzeit über Schlichtebecken CONST num nt1Abtropfen:=4; CONST num nt2Abtropfen:=3; !Merker, Funktionstaste VAR num nFkey; !Abbruch bei falscher Auswahl CONST errnum erAnwahl:=95; CONST errnum erOfenFrei:=95; !* Teilgewicht für 99 Typen * PERS loaddata loAlleTypen{99}:=[[24,[0,0,400],[1,0,0,0],0,0,0],[20,[0,0,400],[1 PERS loaddata loKerntyp:=[24,[0,0,400],[1,0,0,0],0,0,0];
!********************************************************** !* Prozedur haupt() * !* * !* Diese Routine steuert den kompletten Zyklus des * !* Roboters. * !* * !* Date: Version: Programmer: Reason: * !* 16.09.2002 1.0 O.Salo created * !* 28.05.2004 2.0 M.Majewski modify * !********************************************************** PROC haupt() !Hauptprogramm, Neustart von hier
!Startwerte setzen !Stand: 29.05.2004 12:00 Init; !Bremsscheibentyp von KSM einlesen TypEinlesen; GrTypEinl; !von Homepos zur Vorpos KSM IF nGreiferTyp=1 mvHome_10VPA; IF nGreiferTyp=2 mvHome_10VPB; !Anwahl Greiferwechsel an KSM IF diGreiferWechsel=1 GreiferWechsel; !Typnummer und Greifercode prüfen CheckGreiferTyp; !Anwahl Fingerwechsel an KSM IF diGrFingWechsel=1 AND nGreiferTyp=1 FingerWechselA; IF diGrFingWechsel=1 AND nGreiferTyp=2 FingerWechselB; CheckGreifer; ProgInfo; !Produktion bis Roboter zur Homepos angewählt ist WHILE diIRBzurHome=0 DO !warten auf Freigabe von KSM IF diKSMentladen=1 Produktion; IF diSchutztuer=1 OR diTaktEnde=1 Stop; ENDWHILE IF nGreiferTyp=1 mv10VPA_Home; IF nGreiferTyp=2 mv10VPB_Home; GreiferAus; Set doIRBausKSM; Set doIRBausBand; EXIT; ENDPROC
!********************************************************** !* Prozedur TypEinlesen() * !* * !* Diese Prozedur liest beim Start von Haupt die * !* aktuelle Typnummer von der KSM ein. *
!* * !* Date: Version: Programmer: Reason: * !* 13.08.2002 1.0 M.Majewski created * !********************************************************** PROC TypEinlesen() !Bremsscheibentyp von KSM einlesen ! nTyp:=giTyp_Wahl; !Wertebereich des eingelesenen Wertes prüfen !max. 99 Typen möglich IF nTyp<1 OR nTyp>99 THEN Message fmTypWert; Stop; EXIT; ENDIF !Typnummer für den dynamischen Aufruf !der Bewegungsprogramme zuweisen stTyp:=NumToStr(nTyp,0); !Typ an KSM zurückmelden SetGO goTyp_Wahl,nTyp; !aktuelles Kerngewicht zuweisen loKerntyp:=loAlleTypen{nTyp}; ENDPROC
!********************************************************** !* Prozedur GrTypEinl() * !* * !* Diese Prozedur liest beim Start von Haupt die * !* aktuelle Greifernummer von der KSM ein. * !* * !* Date: Version: Programmer: Reason: * !* 26.09.2002 1.0 O.Salo created * !********************************************************** PROC GrTypEinl() !Greifercodierung vom Greifer einlesen ! nGreiferTyp:=0; !Kontrolle der Greifercodierung WHILE diGreiferCode1=0 AND diGreiferCode2=0 DO !kein Greifer am Roboter Message fmGreiferCode0; Stop; ENDWHILE WHILE diGreiferCode1=1 AND diGreiferCode2=1 DO !beide Greifercodierungen belegt Message fmGreiferCode1; Stop; RETURN; ENDWHILE IF diGreiferCode1=1 nGreiferTyp:=1; IF diGreiferCode2=1 nGreiferTyp:=2; !Wertebereich des eingelesenen Wertes prüfen !max. 2 Typen möglich IF nGreiferTyp<1 OR nGreiferTyp>2 THEN Message fmGrTypWert; Stop; EXIT; ENDIF !Typnummer für den dynamischen Aufruf !der Bewegungsprogramme zuweisen stGreiferTyp:=NumToStr(nGreiferTyp,0); IF nGreiferTyp=1 Set doGreifTyp1; IF nGreiferTyp=2 Set doGreifTyp2; ENDPROC
!* 13.08.2002 1.0 M.Majewski created * !********************************************************** PROC Produktion() !Roboter auf Vorpos KSM (10) KernEntnehmen; !An-/Abwahl Entgratstatation IF diMitEntgraten=0 AND diOhneEntgraten=0 RAISE erAnwahl; IF diMitEntgraten=1 THEN !von KSM zum Entgraten IF nGreiferTyp=1 mv10EPA_20VPA; IF nGreiferTyp=2 mv10EPB_20VPB; Entgraten; !vom Entgraten zum Tauchbecken IF diMitKontrolle=1 Inspektion; IF nGreiferTyp=1 mv20EPA_30VPA; IF nGreiferTyp=2 mv20EPB_30VPB; ELSEIF diOhneEntgraten=1 THEN !von KSM zum Entgraten IF nGreiferTyp=1 mv10EPA_20VPA; IF nGreiferTyp=2 mv10EPB_20VPB; IF diMitKontrolle=1 Inspektion; !vom Entgraten zum Tauchbecken IF nGreiferTyp=1 mv20EPA_30VPA; IF nGreiferTyp=2 mv20EPB_30VPB; ENDIF !An-/Abwahl Tauchbecken IF diMitTauchen=0 AND diOhneTauchen=0 RAISE erAnwahl; IF diMitTauchen=1 THEN Tauchen; ELSEIF diOhneTauchen=1 THEN !vom Tauchen zum Auslaufband IF nGreiferTyp=1 mv30EPA_40VPA; IF nGreiferTyp=2 mv30EPB_40VPB; ENDIF !Bremsscheiben auf Auslaufband ablegen IF diMitTauchen=1 AND nGreiferTyp=1 mv30EPA_40VPA; IF diMitTauchen=1 AND nGreiferTyp=2 mv30EPB_40VPB; KernAblegen; !zurück zur KSM IF nGreiferTyp=1 THEN !Zykluszähler nur beim Tauchen erhöhen IF diMitTauchen=1 Incr nZaehlerReinigen; IF nZaehlerReinigen>=nAnzahlReinigen AND nAnzahlReinigen<>0 THEN Clear nZaehlerReinigen; !mit Reinigung Greifer A mv40EPA_50RPA; mv50RPA_10VPA; ELSE !direkt zurück zur KSM mv40EPA_10VPA; ENDIF ENDIF IF nGreiferTyp=2 mv40EPB_10VPB; bProgInfo:=TRUE; ERROR IF ERRNO=erAnwahl THEN Message fmAnwahl; Stop; RETRY; ENDIF ENDPROC
!Kern aus der Kernschießmaschine entnehmen ! Reset doIRBausKSM; Reset doKSMentladen; GreiferLoesen; !von Vorpos zu Greifpos KSM !mvGr1_10VP_10GP1 %"mvGr"+stGreiferTyp+"10VP_10GP"+stTyp%; GreiferSpannen; Set doKSMentladen; !von Greifpos zu Endpos KSM !mvGr1_10GP1_10EP %"mvGr"+stGreiferTyp+"10GP"+stTyp+"_10EP"%; Set doIRBausKSM; ERROR !wenn der dynamische Programmaufruf falsch ist IF ERRNO=ERR_CALLPROC OR ERRNO=ERR_REFUNKPRC THEN Message fmDynamAufruf; TPWrite " "; TPWrite "mvGr"+stGreiferTyp+"10VP_10GP"+stTyp+" oder mvGr"+stGreiferTyp+"10 TPReadFK nFkey,"Prozedur existiert nicht !","EXIT","","","",""; EXIT; ENDIF ENDPROC
!********************************************************** !* Prozedur Entgraten() * !* * !* Date: Version: Programmer: Reason: * !* 13.08.2002 1.0 M.Majewski created * !********************************************************** PROC Entgraten() !Entgraten ! !von Vorpos zu Entgratpos KSM !mv20VP_20EgP1 %"mv20VP_20EgP"+stTyp%; !von Entgratpos 1 zu Endpos KSM !mv20EgP1_20EP %"mv20EgP"+stTyp+"_20EP"%; ERROR !wenn der dynamische Programmaufruf falsch ist IF ERRNO=ERR_CALLPROC OR ERRNO=ERR_REFUNKPRC THEN Message fmDynamAufruf; TPWrite " "; TPWrite " mv20VP_20EgP"+stTyp+" oder mv20EgP"+stTyp+"_20EP"; TPReadFK nFkey,"Prozedur existiert nicht !","EXIT","","","",""; EXIT; ENDIF ENDPROC
!********************************************************** !* Prozedur Tauchen() * !* * !* Date: Version: Programmer: Reason: * !* 13.08.2002 1.0 M.Majewski created * !********************************************************** PROC Tauchen() !Tauchen ! Motor zum Tauchen einschalten GreiferDrehen; !von Vorpos zu Tauchpos !mv30VP_30TP1 %"mv30VP_30TP"+stTyp%; !Tauchzeit WaitTime ntTauchen; ! Motor AUS !von Tauchpos zu Tropfposition !mv30TP1_30AP1 %"mv30TP"+stTyp+"_31AP"+stTyp%; ! Motor zum abtropfen einschalten
GreiferDrehen; !Abtropfzeit WaitTime nt1Abtropfen; !von Abtropfpos 1 zu Abtropfpos2 !mv31AP1_32AP1 %"mv31AP"+stTyp+"_32AP"+stTyp%; !Abtropfzeit WaitTime nt2Abtropfen; ! Motor AUS IF nGreiferTyp=2 WaitDI diGraufPos,1; GreiferStop; !von Abtropfpos zu Endpos !mv32AP1_30EP %"mv32AP"+stTyp+"_30EP"%; ERROR !wenn der dynamische Programmaufruf falsch ist IF ERRNO=ERR_CALLPROC OR ERRNO=ERR_REFUNKPRC THEN Message fmDynamAufruf; TPWrite " "; TPWrite " mv30VP_30TP"+stTyp+" oder mv30TP"+stTyp+"_30EP"; TPReadFK nFkey,"Prozedur existiert nicht !","EXIT","","","",""; EXIT; ENDIF ENDPROC
!********************************************************** !* Prozedur KernAblegen() * !* * !* Kerne auf Auslaufband ablegen. * !* * !* Date: Version: Programmer: Reason: * !* 13.08.2002 1.0 M.Majewski created * !********************************************************** PROC KernAblegen() !Kerne auf Auslaufband ablegen ! WaitMsgDI diBandBereit,1,fmAblageFrei; ! Kern ablegen Reset doIRBausBand; Reset doAufBandAbgel; !von Vorpos zu Ablagepos Auslaufband !mv40VP_41AP %"mv40VP_40AP"+stTyp%; GreiferLoesen; Set doAufBandAbgel; !von Ablagepos zu Endpos Band !mv41AP1_40EP %"mv40AP"+stTyp+"_40EP"%; Set doIRBausBand; ERROR !wenn der dynamische Programmaufruf falsch ist IF ERRNO=ERR_CALLPROC OR ERRNO=ERR_REFUNKPRC THEN Message fmDynamAufruf; TPWrite " "; TPWrite " mv40VP_40AP"+stTyp+" oder mv40AP"+stTyp+"_40EP"; TPReadFK nFkey,"Prozedur existiert nicht !","EXIT","","","",""; EXIT; ENDIF ENDPROC
!********************************************************** !* Prozedur Inspektion() * !* * !* Inspektion durch Sichtprüfung mit Quittierung. * !* * !* Date: Version: Programmer: Reason: * !* 12.05.2004 1.0 M.Majewski created * !********************************************************** PROC Inspektion() !Kerninspektion durch Sichtkontrolle IF nGreiferTyp=1 mv20EPA_70VPA;
IF nGreiferTyp=2 mv20EPB_70VPB; !zur ersten Kontrollpos IF nGreiferTyp=1 mv70VPA_71KPA; IF nGreiferTyp=2 mv70VPB_71KPB; !Quittiertaster betätigen WaitMsgDI diKontrQuitt,1,fmInspektion; !zur zweiten Kontrollpos IF nGreiferTyp=1 mv71KPA_72KPA; IF nGreiferTyp=2 mv71KPB_72KPB; !Quittiertaster betätigen WaitMsgDI diKontrQuitt,1,fmInspektion; !zur Endpos Inspektion IF nGreiferTyp=1 mv72KPA_70EPA; IF nGreiferTyp=2 mv72KPB_70EPB; !zurück zur Endpos Entgraten IF nGreiferTyp=1 mv70EPA_20EPA; IF nGreiferTyp=2 mv70EPB_20EPB; ENDPROC
!********************************************************** !* Prozedur CheckGreiferTyp() * !* * !* Date: Version: Programmer: Reason: * !* 28.05.2004 1.0 M.Majewski created * !********************************************************** PROC CheckGreiferTyp() !Check Greifertyp !Kontrolle der Greifercodierung WHILE diGreiferCode1=0 AND diGreiferCode2=0 DO !kein Greifer am Roboter Message fmGreiferCode0; Stop; ENDWHILE WHILE diGreiferCode1=1 AND diGreiferCode2=1 DO !beide Greifercodierungen belegt Message fmGreiferCode1; Stop; RETURN; ENDWHILE !Typnummer und Greifercodierung prüfen IF nTyp>0 AND nTyp<=30 THEN !Typnummer 1 - 30 werden mit Greifer A produziert GrTypEinl; IF diGreiferCode1=1 RETURN; ELSEIF nTyp>30 AND nTyp<=99 THEN !Typnummer 31 - 99 werden mit Greifer B produziert GrTypEinl; IF diGreiferCode2=1 RETURN; ENDIF !wenn Typnummer und Greifercode nicht passen !dann Greifer wechseln GreiferWechsel; GrTypEinl; ENDPROC
!* * !* Diese Prozedur wechselt den aktuellen Greifer. * !* * !* Date: Version: Programmer: Reason: * !* 28.05.2004 1.1 M.Majewski created * !********************************************************** PROC GreiferWechsel() !Greiferwechsel funktioniert nur bei erfolgreicher Kontrolle !Kontrolle der Greifercodierung WHILE diGreiferCode1=0 AND diGreiferCode2=0 DO !kein Greifer am Roboter Message fmGreiferCode0; Stop; ENDWHILE WHILE diGreiferCode1=1 AND diGreiferCode2=1 DO !beide Greifercodierungen belegt Message fmGreiferCode1; Stop; RETURN; ENDWHILE !Kontrolle des Ablageplatzes IF diGrAblage1Frei=0 AND diGrAblage2Frei=0 THEN !kein Greifer zum Wechseln vorhanden Message fmGrTypWert; Stop; IF nGreiferTyp=1 mv10VPA_Home; IF nGreiferTyp=2 mv10VPB_Home; EXIT; ELSEIF diGrAblage1Frei=1 AND diGrAblage2Frei=1 THEN !beide Ablageplätze belegt Message fmAllesBelegt; Stop; IF nGreiferTyp=1 mv10VPA_Home; IF nGreiferTyp=2 mv10VPB_Home; EXIT; ENDIF !VP -> Vorpos, EP -> Endpos !GAP -> Greif- und Ablagepos !Ws -> Wechselsystem IF diGrAblage1Frei=1 AND diGreiferCode1=1 THEN !von Vorpos KSM nach Vorpos Greiferwechsel mv10VPA_60VPA; !Greifer A ablegen GreiferSpannen; GripLoad load0; mv60VPA_60GAPA; WsAUF; Set doWSAbblasen; !Greifer B holen mv60GAPA_60GAPB; Reset doWSAbblasen; WsZU; GreiferSpannen; GripLoad load0; mv60GAPB_60EPB; !von Endpos Greiferwechsel zu Vorpos KSM mv60EPB_10VPB; ELSEIF diGrAblage2Frei=1 AND diGreiferCode2=1 THEN !von Vorpos KSM nach Vorpos Greiferwechsel mv10VPB_60VPB; !Greifer B ablegen GreiferSpannen; GripLoad load0; mv60VPB_60GAPB; WsAUF; Set doWSAbblasen; !Greifer A holen mv60GAPB_60GAPA; Reset doWSAbblasen; WsZU; GreiferSpannen;
MODULE Einricht VAR jointtarget jpos10:=[[-112.82,13.9,-12.94,0.03,102.91,1.81],[9E+09,9E+09,9E
!********************************************************** !* Procedure CalibrierPos * !* * !* Diese Routine bewegt den Roboter in die Calibrier- * !* position. Hier kann anhand der Nonien der 0-Punkt * !* überprüft werden * !* Dieser Test sollte z.B. nach dem Booten oder nach * !* dem Countersetzen durchgeführt werden * !* * !* Date: Version: Programmer: Reason: * !* 13.08.2002 1.0 M.Majewski created * !********************************************************** PROC CalibrierPos() TPErase; TPWrite " Calibrier-Position"; TPWrite " ------------------"; TPWrite " "; TPWrite "Bewegung zur Sync-Position 0:"; TPWrite " Achse 1 0 deg"; TPWrite " 2 0 deg"; TPWrite " 3 0 deg"; TPReadFK nFkey,"Zur Calibrierposition fahren ?","JA","","","","NEIN"; IF nFkey=1 THEN MoveAbsJ [[0,0,0,0,0,0],[0,9E+09,9E+09,9E+09,9E+09,9E+09]],v200,fine,tGreif Stop; ELSE EXIT;
!Fehlernummer für Programmabbruch CONST errnum erAbbruch:=88; !Merker ob der Inhalt der Triggervariablen initialisiert ist VAR bool bInitTrigger:=FALSE; !Merker fuer Ausgabe der ProgInfo VAR bool bProgInfo:=FALSE; !Name des Kunden PERS string stKunde:="Hottinger 1/Busch Eisenwerke"; !Bezeichnung der Anlage PERS string stAnlage:="ABB Entnahmeroboter Maschine 1502"; !Robotertyp und Seriennummer PERS string stRobNr:="IRB64-10478"; !Name des Programmiers PERS string stProgrammierer:="M.Majewski"; !Zusatzinformation zur Programminfo (z.B. Bezeichnung des Bauteils) PERS string stInfo1:=""; PERS string stInfo2:=""; PERS string stInfo3:=""; !Version der letzen Programmänderung PERS string stVersion:="29.05.2004"; !Merker zum erneuten Anzeigen der Meldung nach einem Programmstop VAR bool bNeuAnzeige:=FALSE; !Merker ob der Inhalt der Triggervariablen erhalten ist VAR bool bInitTrigg:=FALSE; !clock zum Messen der Taktzeit VAR clock cl_Zeit; !********************************************************** !* Weltzonen Variablen * !********************************************************** !Volumen-Daten für die Homeposition VAR shapedata shHomePos; !Weltzone für die Überwachung der Homeposition VAR wzstationary wzHomePos:=[0]; !********************************************************** !* Meldungen * !********************************************************** CONST string stAuto_Manuell:="Wählen Sie MANUELL oder AUTO"; CONST string stWeiter_Abbruch:="Wählen Sie Weiter oder Abbruch !"; CONST string stManuell:="MANUELL"; CONST string stAuto:="AUTO"; CONST string stOK:="OK"; CONST string stWeiter:="Weiter"; CONST string stAbbruch:="Abbruch"; ! CONST string tmInHome{7}:=["-1"," Roboter ist in der Grundstellung"," "," ", CONST string tmNotInHome{7}:=["-1"," Roboter ist nicht in der Grundstellung"," CONST string tmAutoHome{7}:=["-1"," Sie haben AUTOMATIC gewählt !!!"," "," CONST string tmManualHome{7}:=["-1"," Sie haben MANUELL gewählt !!!"," "," CONST string tmOP_Auto{7}:=["-1"," Der Roboter befindet sich in der"," CONST string tmOP_MAN_PROG{7}:=["-1"," Der Roboter befindet sich nicht","
!********************************************************** !* Prozedur CheckHomepos * !* * !* CheckHomePos wird verwendet um zu überprüfen ob der * !* Roboter sich in seiner Homeposition befindet. * !* Steht er nicht in der Homeposition, so wird ein Menü * !* angeboten um den Roboter manuell oder automatisch * !* über die Prozedur mvHomePos in die Homeposition zu * !* fahren. * !* * !* Date: Version: Programmer: Reason: * !* 06.06.96 1.0 B. Schmitt created * !* 23.02.2001 2.0 B. Schmitt Betriebsarten* !********************************************************** PROC CheckHomePos() VAR num nFKey;
!Prüfen ob sich der Roboter in der Homeposition befindet WHILE diIRBinHome=low DO !Roboter muss im Handbetrieb sein
WHILE OpMode()<>OP_MAN_PROG DO Message tmOP_MAN_PROG; TPReadFK nFKey,"",stOK,"","","",""; Stop; ENDWHILE Message tmNotInHome; TPReadFK nFKey,stAuto_Manuell,stManuell,"","","",stAuto; IF nFKey=5 AND OpMode()=OP_MAN_PROG THEN Message tmAutoHome; TPReadFK nFKey,Center(stWeiter_Abbruch),stWeiter,"","","",stAbbruch; IF nFKey=1 AND OpMode()=OP_MAN_PROG THEN %"mvHomePos"%; IF diIRBinHome=high THEN Message tmOP_Auto; TPReadFK nFKey,"",stOK,"","","",""; !Stop; ENDIF ELSE EXIT; ENDIF ELSE TPErase; Message tmManualHome; TPReadFK nFKey,"",stOK,"","","",""; EXIT; ENDIF ENDWHILE Message tmInHome; WaitTime 0.5; TPErase; ENDPROC
!********************************************************** !* Procedure Message * !* * !* Eine Fehlermeldung wird aus dem PG ausgeben. * !* Die Fehlermeldung besteht aus einem String-Datenfeld * !* das die Störungnummer sowie vier Zeilen Text enthält. * !* * !* Ist die Störungsnummer größer als Null, so wird die * !* Störungsnummer an die SPS gemeldet und die Meldung * !* wird in der Error-Log des Roboters gespeichert. * !* * !* Störungsnummern: * !* <0 : Ausgabe ohne Header * !* =0 : Meldung * !* >0 : Störung * !* * !* Date: Version: Programmer: Reason: * !* 16.02.2000 1.0 B. Schmitt created * !********************************************************** PROC Message( string fmMessage{*} \string Header \string Info)
VAR bool bOK; VAR num nErrorNo; VAR string stTitel; CONST string stStoerung:="Störung"; CONST string stMeldung:="Meldung";
!Auslesen der Störungsnummer aus dem ersten Datenfeld bOK:=StrToVal(fmMessage{1},nErrorNo); !Auswahl der Meldungsüberschrift IF Present(Header) THEN stTitel:=Header+" "+fmMessage{1}; ELSEIF nErrorNo>0 THEN stTitel:=stStoerung+" "+fmMessage{1}; ELSE stTitel:=stMeldung;
ENDIF TPErase; TPWrite " "; IF nErrorNo>=0 THEN TPWrite "\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06 TPWrite Center(stTitel); TPWrite "\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06 ENDIF FOR i FROM 2 TO Dim(fmMessage,1) DO TPWrite fmMessage{i}; ENDFOR !Ausgabe der Zusatzmeldung IF Present(Info) TPWrite Info; !Störung muss von SPS oder über das PG quittiert werden IF nErrorNo>0 THEN !Fehlermeldung in die System-Error-Log schreiben ErrorLog stTitel,fmMessage\Info?Info; ENDIF !bei Schutzüranforderung -> Programmstop IF diSchutztuer=1 Stop; WaitTime 0.1; ENDPROC
!Routine verlassen, wenn Daten bereits angezeigt wurden IF bProgInfo=FALSE AND Present(Show)=FALSE RETURN; TPErase; TPWrite Center(stKunde); TPWrite Center(stAnlage); TPWrite " "; TPWrite Center(stInfo1); TPWrite Center(stInfo2); TPWrite Center(stInfo3); TPWrite "\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\0 TPWrite stRoboter+": "+stRobNr; IF StrLen(stProgrammierer)>18 THEN TPWrite stAutor+": "+StrPart(stProgrammierer,1,18)+" / "+stVersion; ELSE TPWrite stAutor+": "+stProgrammierer+" / "+stVersion; ENDIF WaitTime 0.1; !Merker um Daten nur einmal anzuzeigen bProgInfo:=FALSE; ENDPROC
!********************************************************** !* Prozedur WaitBreakDI * !* * !* Diese Prozedur wartet auf einen Eingang eine max. * !* Zeit. nach Ablauf der Zeit erfolgt die Meldung * !* welches Signal fehlt. Über den Eingang diIRBzurHome * !* wird die Prozedur durch einen ErrorHandler * !* abgebrochen * !* * !* Über die optionalen Parameter diOr und diAnd kann ein * !* zweiter Eingang über eine ODER- oder UND-Funktion * !* verarbeitet werden. * !* * !* Input Parameter: signaldi diSignal * !* dionum iCondition * !* string stMSG * !* errnum erNo * !* * !* Optionale Parameter: signaldi diOr * !* signaldi diAnd * !* switch Low * !* num MaxTime * !* * !* Date: Version: Programmer: Reason: * !* 12.12.96 1.0 B. Schmitt * !* 18.11.97 2.0 B. Schmitt * !* 28.08.98 3.0 B. Schmitt Opt. Low * !* 16.02.00 4.0 B. Schmitt opt. MaxTime * !* 07.10.01 4.1 M.Majewski opt. XOR * !********************************************************** PROC WaitBreakDI( VAR signaldi diSignal, dionum iCondition \VAR signaldi diOR |VAR signaldi diAND |VAR signaldi diXOR \switch Low, string stMSG{*} \num MaxTime, errnum erNo)
VAR bool bTimeOut; VAR bool bOk; VAR bool bFehler; VAR dionum iOptCond:=high; VAR num nMaxTime;
!Wartezeit festlegen, wird global über ntTimeOut deklariert, wenn keine Max-Z nMaxTime:=ntTimeOut; IF Present(MaxTime) nMaxTime:=MaxTime; !Abfragebedingung für optionalen Eingang bestimmen IF Present(Low) iOptCond:=0; WHILE NOT bOk DO !Auf die Eingänge eine max. Zeit warten, Abbruch mit diIRBzurHome ist mögli IF Present(diOR) THEN WaitUntil diSignal=iCondition OR diOR=iOptCond OR diIRBzurHome=high\MaxTi ELSEIF Present(diAND) THEN WaitUntil (diSignal=iCondition AND diAND=iOptCond) OR diIRBzurHome=high\M ELSEIF Present(diXOR) THEN WaitUntil (diSignal=iCondition XOR diXOR=iOptCond) OR diIRBzurHome=high\M ELSE WaitUntil diSignal=iCondition OR diIRBzurHome=high\MaxTime:=nMaxTime\Time ENDIF !bei Schutzüranforderung -> Programmstop IF diSchutztuer=1 Stop; !Wenn Zeit abgelaufen, dann Fehlermeldung ausgeben IF bTimeOut OR diIRBzurHome=high THEN !Bei Anforderung zur Homeposition Routine mit Errorhandler verlassen IF diIRBzurHome=high RAISE erNo; !Meldung nur einmal generieren IF NOT bFehler OR bNeuAnzeige Message stMSG;
!********************************************************** !* Prozedur WaitMsgDI * !* * !* Diese Prozedur wartet auf einen Eingang eine max. * !* Zeit. nach Ablauf der Zeit erfolgt die Meldung * !* welches Signal fehlt. * !* * !* Über die optionalen Parameter diOr und diAnd kann ein * !* zweiter Eingang über eine ODER- oder UND-Funktion * !* verarbeitet werden. * !* * !* Input Parameter: signaldi diSignal * !* dionum iCondition * !* string stMSG * !* * !* Optionale Parameter: signaldi diOr * !* signaldi diAnd * !* switch Low * !* num MaxTime * !* * !* Date: Version: Programmer: Reason: * !* 16.05.95 1.0 M. Majewski * !* 07.05.97 2.0 B. Schmitt diOr * !* 28.08.98 3.0 B. Schmitt Opt. Low * !* 16.02.00 4.0 B. Schmitt opt. MaxTime* !* 07.10.01 4.1 M.Majewski diXOR * !********************************************************** PROC WaitMsgDI( VAR signaldi diSignal, dionum iCondition \VAR signaldi diOR |VAR signaldi diAND |VAR signaldi diXOR \switch Low, string stMSG{*} \num MaxTime)
VAR bool bTimeout:=FALSE; VAR bool bFehler:=FALSE; VAR bool bOK:=FALSE; VAR dionum iOptCond:=high; VAR num nMaxTime;
!Wartezeit festlegen, wird global über ntTimeOut deklariert, wenn keine Max-Z nMaxTime:=ntTimeOut; IF Present(MaxTime) nMaxTime:=MaxTime; !Abfragebedingung für optionalen Eingang bestimmen IF Present(Low) iOptCond:=0; WHILE NOT bOK DO !Warten auf die erforderlichen Signale IF Present(diOR) THEN WaitUntil diSignal=iCondition OR diOR=iOptCond\MaxTime:=nMaxTime\TimeFlag ELSEIF Present(diAND) THEN WaitUntil diSignal=iCondition AND diAND=iOptCond\MaxTime:=nMaxTime\TimeFl ELSEIF Present(diXOR) THEN WaitUntil diSignal=iCondition XOR diXOR=iOptCond\MaxTime:=nMaxTime\TimeFl ELSE WaitDI diSignal,iCondition\MaxTime:=nMaxTime\TimeFlag:=bTimeout; ENDIF
!bei Schutzüranforderung -> Programmstop IF diSchutztuer=1 Stop; !Anzeigen einer Meldung auf dem Programmiergerät IF bTimeout THEN !Meldung nur einmal generieren IF NOT bFehler OR bNeuAnzeige Message stMSG; bFehler:=TRUE; bNeuAnzeige:=FALSE; ELSE bOK:=TRUE; ENDIF ENDWHILE IF bFehler TPErase; ENDPROC
!********************************************************** !* Procedure WaitTimeDI * !* * !* Diese Prozedur wartet auf einen Eingang eine max. * !* Zeit. nach Ablauf der Zeit erfolgt die Meldung * !* welches Signal fehlt und eine Fehlerbehandlung wird * !* mit der übergebenen Fehlernummer ausgelöst. * !* * !* Input Parameter: signaldi diSignal * !* dionum iCondition * !* string stMSG * !* num nMaxTime * !* errnum erNo * !* * !* Optionale Parameter: signaldi diOr, diAnd * !* * !* Date: Version: Programmer: Reason: * !* 17.06.1998 1.0 B. Schmitt created * !* 28.08.98 2.0 B. Schmitt Optional Low* !* 26.03.99 3.0 B. Thurn diAnd * !* 21.12.2000 4.0 B. Schmitt ntTime1+2 * !********************************************************** PROC WaitTimeDI( VAR signaldi diSignal, dionum iCondition \VAR signaldi diOr |VAR signaldi diAnd \switch Low, string stMSG{*}, num nMaxTime, errnum erNo)
VAR bool bTimeout:=FALSE; VAR dionum iOptCond:=high; VAR num ntTime1; VAR num ntTime2;
!Abfragebedingung für optinonalen Eingang bestimmen IF Present(Low) iOptCond:=0; !Zeitbestimmung für erste Meldung IF nMaxTime>ntTimeOut THEN ntTime1:=ntTimeOut; ntTime2:=nMaxTime-ntTimeOut; ELSE ntTime1:=nMaxTime; ENDIF !Abbruchbedingung IF Present(diOr) THEN WaitUntil diSignal=iCondition OR diOr=iOptCond\MaxTime:=ntTime1\TimeFlag:=b IF bTimeout Message stMSG; IF ntTime2>0 WaitUntil diSignal=iCondition OR diOr=iOptCond\MaxTime:=ntTime ELSEIF Present(diAnd) THEN WaitUntil diSignal=iCondition AND diAnd=iOptCond\MaxTime:=ntTime1\TimeFlag: IF bTimeout Message stMSG; IF ntTime2>0 WaitUntil diSignal=iCondition AND diAnd=iOptCond\MaxTime:=ntTi ELSE
WaitDI diSignal,iCondition\MaxTime:=ntTime1\TimeFlag:=bTimeout; IF bTimeout Message stMSG; IF ntTime2>0 WaitDI diSignal,iCondition\MaxTime:=ntTime2\TimeFlag:=bTimeout ENDIF !Abbruch bei Zeitüberschreitung IF bTimeout RAISE erNo; ERROR RAISE; ENDPROC
!********************************************************** !* Procedure FirstMove * !* * !* Ausblenden des ersten Bewegungspunktes in Automatik. * !* * !* Date: Version: Programmer: Reason: * !* 25.11.01 1.0 M.Majewski created * !********************************************************** PROC FirstMove( \switch L |switch J, robtarget ToPoint, speeddata speed, zonedata zone, INOUT tooldata tool \INOUT wobjdata WObj)
!wenn die Betriebsart des Roboters nicht Automatik ist, !dann diese Position anfahren IF OpMode()<>OP_AUTO THEN IF Present(L) MoveL ToPoint,speed,zone,tool\WObj?WObj; IF NOT Present(L) OR Present(J) MoveJ ToPoint,speed,zone,tool\WObj?WObj; ENDIF BACKWARD IF Present(L) MoveL ToPoint,speed,zone,tool\WObj?WObj; IF NOT Present(L) OR Present(J) MoveJ ToPoint,speed,zone,tool\WObj?WObj; ENDPROC
!********************************************************** !* Function Center * !* * !* Der Text wird zentriert über das PG zurückgegeben * !* * !* Date: Version: Programmer: Reason: * !* 17.04.1998 1.0 B. Schmitt created * !********************************************************** FUNC string Center( string stCenter)
VAR num nBlank;
!Berechnen der erforderlichen Leerzeichen nBlank:=(40-StrLen(stCenter)) DIV 2; IF nBlank>0 THEN FOR i FROM 1 TO nBlank DO stCenter:=" "+stCenter; ENDFOR ENDIF RETURN stCenter; ENDFUNC
!********************************************************** !* Funktion WordWrap * !* * !* Zeilenumbruch am Ende einer Zeile. Der Umbruch * !* erfolgt vorzugsweise an einem Leerzeichen. * !* * !* In dem Eingangsstring wird der verbleibende Text * !* (>40 Zeichen) belassen * !* * !* Date: Version: Programmer: Reason: *
!* 26.04.2000 1.0 B. Schmitt created * !********************************************************** FUNC string WordWrap( INOUT string Text)
VAR string stText; VAR num nBlank;
!Zuweisung der Anfangswerte stText:=Text; !Zeilenumbruch ausführen IF StrLen(stText)>40 THEN !Leerzeichen am Ende der Zeile suchen FOR i FROM 35 TO 40 DO IF StrMemb(stText,i," ") nBlank:=i; ENDFOR !Kein Leerzeichen vorhanden ! IF nBlank=0 nBlank:=40; !Verbleibenden Text umkopieren Text:=StrPart(stText,nBlank+1,StrLen(stText)-nBlank); !Zeile auf nBlank Zeichen begrenzen (max. 40) und zurückgeben RETURN StrPart(stText,1,nBlank); ELSE Text:=""; RETURN stText; ENDIF ERROR RAISE; ENDFUNC
!********************************************************** !* Prozedur ErrorLog * !* * !* Die übergebene Meldung wird in die System-Errorlog * !* geschrieben * !* * !* Date: Version: Programmer: Reason: * !* 13.07.2000 1.0 B. Schmitt created * !* 28.09.2001 2.0 B. Schmitt modified * !********************************************************** LOCAL PROC ErrorLog( string Header, string ReasonArr{*} \string Info)
VAR num nMsgLength; VAR string fmTemp{10}; VAR num nLines:=1; VAR num nMaxLength:=145; VAR string stTemp; VAR string stText; VAR string stInfo;
!Länge des Headers bestimmen nMsgLength:=StrLen(Header); !Zusatzmeldung formatieren IF Present(Info) THEN stInfo:=Trim(Info); !Zusatzmeldung auf 40 Zeichen beschränken IF StrLen(stInfo)>40 stInfo:=StrPart(stInfo,1,40); !Maximale Länge der Meldung bestimmen nMaxLength:=nMaxLength-StrLen(stInfo); ENDIF !Leerzeichen aus erster Meldungszeile entfernen stText:=Trim(ReasonArr{2}); !Störungstext formatieren FOR i FROM 3 TO Dim(ReasonArr,1) DO IF nMsgLength<nMaxLength THEN stTemp:=Trim(ReasonArr{i}); !Zeile ist zu lang IF StrLen(stText)+StrLen(stTemp)>79 THEN
fmTemp{nLines}:=WordWrap(stText); stText:=Trim(stText+" "+stTemp); !Berechnen der Länge der kompletten Meldung für das Error logging Add nMsgLength,StrLen(fmTemp{nLines}); !Neue Zeile beginnen Incr nLines; ELSE !Nächste Zeile ohne Leerzeichen anhängen stText:=Trim(stText+" "+stTemp); !Wenn Zeilelänge größer als 40 Zeichen ist, dann umbrechen und speicher IF StrLen(stText)>=40 THEN fmTemp{nLines}:=WordWrap(stText); !Berechnen der Länge der kompletten Meldung für das Error logging Add nMsgLength,StrLen(fmTemp{nLines}); !Neue Zeile beginnen Incr nLines; ENDIF ENDIF ENDIF ENDFOR !Zeilenrest in Datenfeld aufnehmen IF StrLen(stText)>0 AND nMsgLength<nMaxLength THEN fmTemp{nLines}:=stText; !Berechnen der Länge der kompletten Meldung für das Error logging Add nMsgLength,StrLen(fmTemp{nLines}); ELSE Decr nLines; ENDIF !Länge der letzten Zeile kürzen, da nur 145 Zeichen max. erlaubt sind IF nMsgLength>nMaxLength fmTemp{nLines}:=StrPart(fmTemp{nLines},1,StrLen(fmTe IF Present(Info) THEN !Ausgabe in die System-Error-Log ErrWrite\W,Header,fmTemp{1}\RL2:=fmTemp{2}\RL3:=fmTemp{3}\RL4:=stInfo; ELSE !Ausgabe in die System-Error-Log ErrWrite\W,Header,fmTemp{1}\RL2:=fmTemp{2}\RL3:=fmTemp{3}\RL4:=fmTemp{4}; ENDIF ERROR RAISE; ENDPROC
!********************************************************** !* Funktion Trim * !* * !* Leerzeichen links und rechts eines Strings löschen * !* * !* Date: Version: Programmer: Reason: * !* 26.04.2000 1.0 B. Schmitt created * !********************************************************** LOCAL FUNC string Trim( string Text)
VAR string stText;
stText:=Text; !Prüfen ob ersten Zeichen ein Leerzeichen ist WHILE StrLen(stText)>0 AND StrMemb(stText,1," ") DO !Erstes Zeichen löschen stText:=StrPart(stText,2,StrLen(stText)-1); ENDWHILE !Prüfen ob letztes Zeichen ein Leerzeichen ist WHILE StrLen(stText)>0 AND StrMemb(stText,StrLen(stText)," ") DO !Letztes Zeichen löschen stText:=StrPart(stText,1,StrLen(stText)-1); ENDWHILE RETURN stText; ERROR RAISE; ENDFUNC
!* Funktion RelTCP * !* * !* Diese Funktion veraendert einen TCP relativ zu einem * !* anderen TCP. * !* * !* INPUT : TCP, der veraendert werden soll * !* Verschiebung in X,Y,Z Richtung * !* Winkel fuer Rotation um X,Y,Z Achse * !* OUTPUT : veraenderter TCP * !* * !* Syntax : tool2:=RelTCP(tool1\Dx,\Dy,\Dz,\Rx,\Ry,\Rz); * !* Beispiel: TCP tGreifer1 um y-Achse 10 Grad drehen * !* tGreifer2:=RelTCP(tGreifer1\Ry:=10); * !* * !* Date: Version: Programmer: Reason: * !* 18.03.98 1.0 M.Majewski created * !* 30.10.00 2.0 B. Schmitt PoseMult * !********************************************************** FUNC tooldata RelTCP( INOUT tooldata tTCP \num Dx \num Dy \num Dz \num Rx \num Ry \num Rz)
VAR num nRotX; VAR num nRotY; VAR num nRotZ; VAR tooldata tRelTCP; VAR pose pseFrame:=[[0,0,0],[1,0,0,0]];
!Orginal TCP erhalten tRelTCP:=tTCP; !translatorische Anteile berechnen IF Present(Dx) pseFrame.trans.x:=Dx; IF Present(Dy) pseFrame.trans.y:=Dy; IF Present(Dz) pseFrame.trans.z:=Dz; !Rotationsoffset berechnen IF Present(Rx) nRotX:=Rx; IF Present(Ry) nRotY:=Ry; IF Present(Rz) nRotZ:=Rz; !Euler in Quaternion umwandeln pseFrame.rot:=OrientZYX(nRotZ,nRotY,nRotX); !Verschobenen Tool berechnen tRelTCP.tframe:=PoseMult(tRelTCP.tframe,pseFrame); !veraenderten TCP zurueckgeben RETURN tRelTCP; ENDFUNC
!********************************************************** !* Prozedur ProgStop * !* * !* Ereignisroutine um bei einem Programmstop die * !* ausgegebene Meldung nochmal anzuzeigen. * !* * !* Date: Version: Programmer: Reason: * !* 10.07.1998 1.0 B. Schmitt created * !********************************************************** PROC ProgStop() TPShow TP_PROGRAM; bNeuAnzeige:=TRUE; ENDPROC
!********************************************************** !* Procedure IRS_Logo * !* * !* Das Logo der Firma IRS wird auf dem PG ausgegeben. * !* Die Ausgabezeit wird mit dem Input Parameter * !* Counter festgelegt, ist dieser Parameter nicht ange- *
!* wählt dann wird die Standardausgabe auf 10 Sekunden * !* gesetzt. Ist der optionale Parameter noCountDown * !* angewählt wird nur das Logo angezeigt. * !* * !* Input Parameter: num Counter * !* * !* Optionale Parameter: switch noCountDown * !* * !* Date: Version: Programmer: Reason: * !* 07.10.2001 1.0 M.Majewski created * !********************************************************** PROC IRS_Logo( \switch noCountDown |num Counter)
VAR num nStart:=10;
IF Present(Counter) nStart:=Counter; IF Present(noCountDown) Clear nStart; FOR i FROM nStart TO 0 STEP -1 DO TPErase; TPWrite "\17\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13 TPWrite "\12 \1F \1F\1F\1F \1F\1F I R S \12"; TPWrite "\12 \1F \1F \1F \1F Industrie-Roboter- \12"; TPWrite "\12 \1F \1F\1F\1F \1F Service GmbH \12"; TPWrite "\12 \1F \1F \1F \1F 35325 Mücke \12"; TPWrite "\12 \1F \1F \1F \1F\1F Tel.06400-201851 \12"; TPWrite "\16\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13\13 IF Present(noCountDown) TPWrite " "; TPWrite " aktuelles Datum : "+CDate(); TPWrite " aktuelle Zeit : "+CTime(); IF NOT Present(noCountDown) THEN TPWrite " "; TPWrite " Countdown : = "+ValToStr(i)+" Sekunden"; WaitTime 1; ENDIF ENDFOR IF NOT Present(noCountDown) TPShow TP_LATEST; ENDPROC