Skip to content

Instantly share code, notes, and snippets.

@liminal
Created April 9, 2015 15:54
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save liminal/3e596793685471ccffb1 to your computer and use it in GitHub Desktop.
Save liminal/3e596793685471ccffb1 to your computer and use it in GitHub Desktop.
This is the main program for a pick and place application.
%%%
VERSION:1
LANGUAGE:ENGLISH
%%%
MODULE PPAMAIN
!***********************************************************
!
! File: PMppa340.prg
!
! $Revision: 31 $
!
! Description
! This is the main program for a pick and place
! application.
!
! Copyright (c) ABB Automation Technology Products 2002.
! All rights reserved
!
!***********************************************************
!***********************************************************
!
! Module: PPAMAIN
!
! Description
! This is the main program module for a pick and
! place application.
!
!***********************************************************
!***********************************************************
!
! Procedure main
!
! This is the PickMaster MAIN routine.
!
!***********************************************************
PROC main()
TPWrite "main";
InCoordRout:=FALSE;
InitSafeStop;
InitSpeed;
WHILE TRUE DO
SetDO ppaExe,0;
WaitForExeOrder:=TRUE;
IF RemoteIPNode<>"" THEN
SCWrite\ToNode:=RemoteIPNode,WaitForExeOrder;
ENDIF
WaitDO ppaExe,1;
%RoutineName%;
ENDWHILE
ERROR (PPA_JUMP_MOVE)
IF ERRNO = PPA_JUMP_MOVE THEN
ClearPath;
GotoRestartPos;
RETRY;
ELSEIF ERRNO=ERR_SC_WRITE THEN
TRYNEXT;
ENDIF
ENDPROC
!***********************************************************
!
! Procedure InitSafeStop
!
! This routine initiates the robot stop interrupt.
!
!***********************************************************
PROC InitSafeStop()
Reset doSafeStop;
IDelete SafeStopSignal;
CONNECT SafeStopSignal WITH SafeStopTrap;
ISignalDO doSafeStop, 1, SafeStopSignal;
ENDPROC
!***********************************************************
!
! Procedure InitTriggs
!
! This routine sets the triggdata for the vacuum signals
! for all used item sources.
!
!***********************************************************
PROC InitTriggs()
FOR i FROM 1 TO MaxNoSources DO
IF (ItmSrcData{i}.Used) THEN
SetTriggs i;
ENDIF
ENDFOR
ENDPROC
!***********************************************************
!
! Procedure InitPickTune
!
! This routine initiates the tuning interrupt.
!
!***********************************************************
PROC InitPickTune()
Reset doTune;
IDelete PickTuneInt;
CONNECT PickTuneInt WITH PickTuneTrap;
ISignalDO doTune, 1, PickTuneInt;
ENDPROC
!***********************************************************
!
! Procedure SetTriggs
!
! This routine sets the triggdata for the vacuum signals.
! This will be changed when more than one vacuum ejector
! is used.
!
!***********************************************************
PROC SetTriggs(num Index)
TEST ItmSrcData{Index}.SourceType
CASE PICK_TYPE:
TriggEquip ItmSrcData{Index}.VacuumAct1,0,ItmSrcData{Index}.VacActDelay\GOp:=goVacBlow1,1;
CASE PLACE_TYPE:
TriggEquip ItmSrcData{Index}.VacuumRev1,0,ItmSrcData{Index}.VacRevDelay\GOp:=goVacBlow1,2;
TriggEquip ItmSrcData{Index}.VacuumOff1,0,ItmSrcData{Index}.VacOffDelay\GOp:=goVacBlow1,0;
DEFAULT:
TriggEquip ItmSrcData{Index}.VacuumAct1,0,ItmSrcData{Index}.VacActDelay\GOp:=goVacBlow1,1;
TriggEquip ItmSrcData{Index}.VacuumRev1,0,ItmSrcData{Index}.VacRevDelay\GOp:=goVacBlow1,2;
TriggEquip ItmSrcData{Index}.VacuumOff1,0,ItmSrcData{Index}.VacOffDelay\GOp:=goVacBlow1,0;
ENDTEST
ENDPROC
!***********************************************************
!
! Procedure InitSpeed
!
! This routine sets the speed limits. It may be changed
! in different projects.
!
!***********************************************************
PROC InitSpeed()
MaxSpeed.v_tcp:=Vtcp;
LowSpeed.v_tcp:=Vtcp/3;
VeryLowSpeed.v_tcp:=250;
VelSet 100,10000;
ENDPROC
!***********************************************************
!
! Procedure pickplace
!
! Initiate the final settings before starting the process
! and specify the pick-place cycle.
!
!***********************************************************
PROC PickPlace()
TPWrite "PickPlace";
InCoordRout:=FALSE;
ConfL\Off;
MoveL SafePos,VeryLowSpeed,fine,Gripper\WObj:=wobj0;
SetGO goVacBlow1,0;
WaitTime 0.1;
IndReset IRB,4\RefNum:=0\Short;
WaitTime 0.2;
PickPlaceRunning:=TRUE;
IF RemoteIPNode<>"" THEN
SCWrite\ToNode:=RemoteIPNode,PickPlaceRunning;
ENDIF
IF FirstTime=TRUE THEN
FOR i FROM 1 TO MaxNoSources DO
IF (ItmSrcData{i}.Used) THEN
QStartItmSrc ItmSrcData{i}.ItemSource;
ENDIF
ENDFOR
SetupIndexes;
InitTriggs;
InitPickTune;
PickRateInit;
FirstTime:=FALSE;
WaitTime 0.2;
ENDIF
WHILE TRUE DO
FOR i FROM 1 TO 2000 DO
IF (StopProcess = TRUE) THEN
StopProcess:=FALSE;
SafeStop;
ENDIF
PickPlaceSeq;
Incr Picks;
ENDFOR
MoveL SafePos,MaxSpeed,fine,Gripper\WObj:=wobj0;
WaitTime 0.1;
IndReset IRB,4\RefNum:=0\Short;
WaitTime 0.2;
ENDWHILE
ERROR
IF ERRNO=ERR_SC_WRITE THEN
TRYNEXT;
ENDIF
ENDPROC
!***********************************************************
!
! Procedure SafeStop
!
! This routine execute a movement to the SafeStop
! position and resets some variables.
!
!***********************************************************
PROC SafeStop()
VAR string time;
VAR string date;
InCoordRout:=FALSE;
SafeStopExecuted:=FALSE;
IDelete SafeStopSignal;
TPWrite "Safe stop requested "+CDate()+" "+CTime();
GotoRestartPos;
WaitTime 0.1;
IndReset IRB,4\RefNum:=0\Short;
WaitTime 0.2;
StopProcess:=FALSE;
SafeStopExecuted:=TRUE;
IF RemoteIPNode<>"" THEN
SCWrite\ToNode:=RemoteIPNode,SafeStopExecuted;
ENDIF
ExitCycle;
ERROR
IF ERRNO=ERR_SC_WRITE THEN
TRYNEXT;
ENDIF
ENDPROC
!***********************************************************
!
! Procedure GotoRestartPos
!
! This routine moves the robot to the SafePos and will
! also acknowledge all item sources so the execution can
! be restarted.
!
!***********************************************************
PROC GotoRestartPos()
FOR i FROM 1 TO MaxNoSources DO
IF (ItmSrcData{i}.Used) THEN
TriggL SafePos,VeryLowSpeed,ItmSrcData{i}.Nack,fine,Gripper\WObj:=wobj0;
ENDIF
ENDFOR
SetGO goVacBlow1,0;
ENDPROC
!**********************************************************
!
! Trap SafeStopTrap
!
! This trap will run the SafeStop routine.
!
!**********************************************************
TRAP SafeStopTrap
Reset doSafeStop;
SafeStop;
ENDTRAP
!**********************************************************
!
! Trap PickTuneTrap
!
! This trap sets the tune datas.
!
!**********************************************************
TRAP PickTuneTrap
Reset doTune;
TEST TuneType
CASE SPEED_TUNE:
MaxSpeed.v_tcp:=Vtcp;
LowSpeed.v_tcp:=Vtcp/3;
CASE PICKPLACE_TUNE:
IF ItmSrcData{SourceIndex}.Used THEN
IF (ItmSrcData{SourceIndex}.SourceType = PICK_TYPE) THEN
ItmSrcData{SourceIndex}.VacActDelay:=VacActDelay;
ELSEIF (ItmSrcData{SourceIndex}.SourceType = PLACE_TYPE) THEN
ItmSrcData{SourceIndex}.VacRevDelay:=VacRevDelay;
ItmSrcData{SourceIndex}.VacOffDelay:=VacOffDelay;
ELSE
ItmSrcData{SourceIndex}.VacActDelay:=VacActDelay;
ItmSrcData{SourceIndex}.VacRevDelay:=VacRevDelay;
ItmSrcData{SourceIndex}.VacOffDelay:=VacOffDelay;
ENDIF
IF ItmSrcData{SourceIndex}.TrackPoint.Type = fllwtime THEN
ItmSrcData{SourceIndex}.TrackPoint.followtime:=FollowTime;
ELSEIF ItmSrcData{SourceIndex}.TrackPoint.Type = stoptime THEN
ItmSrcData{SourceIndex}.TrackPoint.stoptime:=FollowTime;
ENDIF
ItmSrcData{SourceIndex}.OffsZ:=OffsZ;
SetTriggs SourceIndex;
ELSE
ErrWrite "Tune not possible ","The workarea index "+ValToStr(SourceIndex)+" is an unused index";
ENDIF
ENDTEST
ENDTRAP
ENDMODULE
MODULE PPASERVICE
!***********************************************************
!
! Module: PPASERVICE
!
! Description
! This program module includes all service modules
! that i able to run from PickMaster.
! All service routine names and service variable should
! be inserted in the persistant variables to be
! recognized by PickMaster.
!
!***********************************************************
PERS string ServiceRoutine1:="Home";
PERS string ServiceRoutine2:="WashDown";
PERS string ServiceRoutine3:="TestCycle";
PERS string ServiceRoutine4:="Homepos";
PERS string ServiceRoutine5:="";
PERS string ServiceRoutine6:="";
PERS string ServiceRoutine7:="";
PERS string ServiceRoutine8:="";
PERS string ServiceRoutine9:="";
PERS string ServiceRoutine10:="";
PERS string ServiceVar1:="ServVar1";
PERS string ServiceVar2:="ServVar2";
PERS string ServiceVar3:="ServVar3";
PERS string ServiceVar4:="";
PERS string ServiceVar5:="";
PERS string ServiceVar6:="";
PERS string ServiceVar7:="";
PERS string ServiceVar8:="";
PERS string ServiceVar9:="";
PERS string ServiceVar10:="";
PERS num ServVar1:=0;
PERS num ServVar2:=0;
PERS num ServVar3:=0;
!***********************************************************
!
! Procedure Home
!
! Service routine
!
!***********************************************************
PROC Home()
MoveL SafePos,VeryLowSpeed,fine,Gripper\WObj:=wobj0;
TPWrite "Home Routine executed";
ExitCycle;
ENDPROC
!***********************************************************
!
! Procedure WashDown
!
! Service routine
!
!***********************************************************
PROC WashDown()
TPWrite "WashDown Routine executed";
ExitCycle;
ENDPROC
!***********************************************************
!
! Procedure TestCycle
!
! Service routine
!
!***********************************************************
PROC TestCycle()
TPWrite "TestCycle Routine executed";
ExitCycle;
ENDPROC
!***********************************************************
!
! Procedure Homepos
!
! Service routine
!
!***********************************************************
PROC Homepos()
MoveAbsJ [[-11,-11,-11,0,0,0],[0,0,0,0,0,0]]\NoEOffs,VeryLowSpeed,fine,Gripper\WObj:=wobj0;
ExitCycle;
ENDPROC
ENDMODULE
MODULE PPAEXECUTING
!***********************************************************
!
! Module: PPAEXECUTING
!
! Description
! This program module executes all movements when the
! process is running.
! Edit this module to customize the project.
!
!***********************************************************
VAR num PickIndex1:=0;
VAR num PickIndex2:=0;
VAR num PickIndex3:=0;
VAR num PickIndex4:=0;
VAR num PickIndex5:=0;
VAR num PickIndex6:=0;
VAR num PickIndex7:=0;
VAR num PickIndex8:=0;
VAR num PlaceIndex1:=0;
VAR num PlaceIndex2:=0;
VAR num PlaceIndex3:=0;
VAR num PlaceIndex4:=0;
VAR num PlaceIndex5:=0;
VAR num PlaceIndex6:=0;
VAR num PlaceIndex7:=0;
VAR num PlaceIndex8:=0;
VAR num OtherIndex1:=0;
VAR num OtherIndex2:=0;
VAR num OtherIndex3:=0;
VAR num OtherIndex4:=0;
VAR num OtherIndex5:=0;
VAR num OtherIndex6:=0;
VAR num OtherIndex7:=0;
VAR num OtherIndex8:=0;
! Definition of the item targets, are temporarely used in the pick and place routines.
VAR itmtgt PickTarget:=[0,0,0,[[0,0,0],[0,-1,0,0],[0,0,0,0],[0,0,0,0,0,0]]];
VAR itmtgt PlaceTarget:=[0,0,0,[[0,0,0],[0,-1,0,0],[0,0,0,0],[0,0,0,0,0,0]]];
PERS wobjdata WObjPick:=[FALSE,TRUE,"",[[0,0,0],[1,0,0,0]],[[0,0,0],[1,0,0,0]]];
PERS wobjdata WObjPlace:=[FALSE,TRUE,"",[[0,0,0],[1,0,0,0]],[[0,0,0],[1,0,0,0]]];
! Safe/stop position and where the intermediate points before pick/place should be placed.
PERS robtarget SafePos:=[[0,0,-1000],[0,-1,0,0],[0,0,0,0],[0,0,0,0,0,0]];
! Set the TCP location and the tool load for current tool.
PERS tooldata Gripper:=[TRUE,[[0,0,50],[1,0,0,0]],[0.1,[0,0,0.001],[1,0,0,0],0,0,0]];
! Set the payload for the items which is picked.
PERS loaddata ItemLoad:=[0.001,[0,0,0.001],[1,0,0,0],0,0,0];
!***********************************************************
!
! Procedure SetupIndexes
!
! Sets up the correct indexes for the different.
! The index is the same as the one that is set in the
! PickMaster workarea.
! The default setup is only made to catch all workareas.
! Customize this for each project to get the correct
! indexes.
!
!***********************************************************
PROC SetupIndexes()
PickIndex1:=0;
PickIndex2:=0;
PickIndex3:=0;
PickIndex4:=0;
PickIndex5:=0;
PickIndex6:=0;
PickIndex7:=0;
PickIndex8:=0;
PlaceIndex1:=0;
PlaceIndex2:=0;
PlaceIndex3:=0;
PlaceIndex4:=0;
PlaceIndex5:=0;
PlaceIndex6:=0;
PlaceIndex7:=0;
PlaceIndex8:=0;
OtherIndex1:=0;
OtherIndex2:=0;
OtherIndex3:=0;
OtherIndex4:=0;
OtherIndex5:=0;
OtherIndex6:=0;
OtherIndex7:=0;
OtherIndex8:=0;
FOR i FROM 1 TO MaxNoSources DO
IF (ItmSrcData{i}.Used) THEN
IF (ItmSrcData{i}.SourceType = PICK_TYPE) THEN
IF (PickIndex1 = 0) THEN
PickIndex1:=i;
ELSEIF (PickIndex2 = 0) THEN
PickIndex2:=i;
ELSEIF (PickIndex3 = 0) THEN
PickIndex3:=i;
ELSEIF (PickIndex4 = 0) THEN
PickIndex4:=i;
ELSEIF (PickIndex5 = 0) THEN
PickIndex5:=i;
ELSEIF (PickIndex6 = 0) THEN
PickIndex6:=i;
ELSEIF (PickIndex7 = 0) THEN
PickIndex7:=i;
ELSEIF (PickIndex8 = 0) THEN
PickIndex8:=i;
ENDIF
ELSEIF (ItmSrcData{i}.SourceType = PLACE_TYPE) THEN
IF (PlaceIndex1 = 0) THEN
PlaceIndex1:=i;
ELSEIF (PlaceIndex2 = 0) THEN
PlaceIndex2:=i;
ELSEIF (PlaceIndex3 = 0) THEN
PlaceIndex3:=i;
ELSEIF (PlaceIndex4 = 0) THEN
PlaceIndex4:=i;
ELSEIF (PlaceIndex5 = 0) THEN
PlaceIndex5:=i;
ELSEIF (PlaceIndex6 = 0) THEN
PlaceIndex6:=i;
ELSEIF (PlaceIndex7 = 0) THEN
PlaceIndex7:=i;
ELSEIF (PlaceIndex8 = 0) THEN
PlaceIndex8:=i;
ENDIF
ELSE
IF (OtherIndex1 = 0) THEN
OtherIndex1:=i;
ELSEIF (OtherIndex2 = 0) THEN
OtherIndex2:=i;
ELSEIF (OtherIndex3 = 0) THEN
OtherIndex3:=i;
ELSEIF (OtherIndex4 = 0) THEN
OtherIndex4:=i;
ELSEIF (OtherIndex5 = 0) THEN
OtherIndex5:=i;
ELSEIF (OtherIndex6 = 0) THEN
OtherIndex6:=i;
ELSEIF (OtherIndex7 = 0) THEN
OtherIndex7:=i;
ELSEIF (OtherIndex8 = 0) THEN
OtherIndex8:=i;
ENDIF
ENDIF
ENDIF
ENDFOR
ENDPROC
!***********************************************************
!
! Procedure PickPlaceSeq
!
! The Pick and Place sequence.
! Edit this routine to specify how the robot shall
! execute the movements.
!
!***********************************************************
PROC PickPlaceSeq()
Pick PickIndex1;
Place PlaceIndex1;
!Place PlaceIndex2;
ENDPROC
!***********************************************************
!
! Procedure Pick
!
! Executes a pick movement
!
!***********************************************************
PROC Pick(num Index)
InCoordRout:=TRUE;
WObjPick:=ItmSrcData{Index}.Wobj;
GetItmTgt ItmSrcData{Index}.ItemSource,PickTarget;
TriggL\Conc,RelTool(PickTarget.RobTgt,0,0,-ItmSrcData{Index}.OffsZ),MaxSpeed,ItmSrcData{Index}.VacuumAct1,z20,Gripper\WObj:=WObjPick;
MoveL\Conc,PickTarget.RobTgt,LowSpeed,z5\Inpos:=ItmSrcData{Index}.TrackPoint,Gripper\WObj:=WObjPick;
GripLoad ItemLoad;
TriggL RelTool(PickTarget.RobTgt,0,0,-ItmSrcData{Index}.OffsZ),LowSpeed,ItmSrcData{Index}.Ack,z20,Gripper\WObj:=WObjPick;
InCoordRout:=FALSE;
ENDPROC
!***********************************************************
!
! Procedure Place
!
! Executes a place movement
!
!***********************************************************
PROC Place(num Index)
InCoordRout:=TRUE;
WObjPlace:=ItmSrcData{Index}.Wobj;
GetItmTgt ItmSrcData{Index}.ItemSource,PlaceTarget;
MoveL\Conc,RelTool(PlaceTarget.RobTgt,0,0,-ItmSrcData{Index}.OffsZ),MaxSpeed,z20,Gripper\WObj:=WObjPlace;
TriggL\Conc,PlaceTarget.RobTgt,LowSpeed,ItmSrcData{Index}.VacuumRev1\T2:=ItmSrcData{Index}.VacuumOff1,z5\Inpos:=ItmSrcData{Index}.TrackPoint,Gripper\WObj:=WObjPlace;
GripLoad load0;
TriggL RelTool(PlaceTarget.RobTgt,0,0,-ItmSrcData{Index}.OffsZ),LowSpeed,ItmSrcData{Index}.Ack,z20,Gripper\WObj:=WObjPlace;
InCoordRout:=FALSE;
ENDPROC
ENDMODULE
%%%
VERSION:1
LANGUAGE:ENGLISH
%%%
MODULE PPACAL
!***********************************************************
!
! Module: PPACAL
!
! $Revision: 1.2 $
!
! Depending on
!
! Description
! This program module prepares CNV1 or CNV2 for
! vision to robot calibration using encoder board DSQC377.
!
! Copyright (c) ABB Robotics Products AB 2000.
! All rights reserved
!
!***********************************************************
PERS tooldata Gripper:=[TRUE,[[0,0,0],[1,0,0,0]],[0.1,[0,0,0.001],[1,0,0,0],0,0,0]];
PERS wobjdata WorkObject:=[FALSE,TRUE,"",[[0,0,0],[1,0,0,0]],[[0,0,0],[1,0,0,0]]];
PERS num RemoteMode:=0;
VAR mecunit CnvMecUnit;
VAR string CnvMecString:="";
VAR datapos block;
VAR num CnvNum:=0;
VAR num IndNum:=0;
VAR num CalibType:=0;
VAR num ConfirmSave:=0;
VAR intnum NewObj;
VAR bool NewObjReported:=FALSE;
VAR num ObjectPosition1:=0;
VAR num ObjectPosition2:=0;
VAR signaldo doRemAllPObj;
VAR signaldo doDropWObj;
VAR signaldo doPosInJobQ;
VAR signaldi diNewObjStrobe;
VAR signaldo doManSync;
VAR signalgi giCount1FromEnc;
VAR signalgi giCount2FromEnc;
VAR signalgo goCount1ToEnc;
VAR signalgo goCount2ToEnc;
VAR signaldo doForceJob;
VAR signaldo doCountToEncStr;
!========================== main ===========================
PROC main()
TPErase;
CalibType:=0;
WorkObject:=wobj0;
IF RemoteMode=0 THEN
CnvName:="";
NonCnvWobjName:="";
TPWrite "WHICH KIND OF CALIBRATION DO YOU WANT TO DO?";
TPReadFK CalibType,"CONVEYOR OR FIXED/INDEXED","","","","Cnv","Ind";
ENDIF
IF CnvName<>"" OR CalibType=4 THEN
IF RemoteMode=0 THEN
TPWrite "Vision to robot calibration.";
TPWrite "DSQC377 version.";
TPReadFK CnvNum,"Choose conveyor","CNV1","CNV2","CNV3","CNV4","MORE";
IF CnvNum=5 THEN
TPReadFK CnvNum,"Choose conveyor","CNV5","CNV6","","","";
CnvNum:=CnvNum+4;
ENDIF
CnvName:="CNV"+ValToStr(CnvNum);
ELSE
TEST CnvName
CASE "CNV1":
CnvNum:=1;
CASE "CNV2":
CnvNum:=2;
CASE "CNV3":
CnvNum:=3;
CASE "CNV4":
CnvNum:=4;
CASE "CNV5":
CnvNum:=5;
CASE "CNV6":
CnvNum:=6;
ENDTEST
ENDIF
GetDataVal "c"+ValToStr(CnvNum)+"RemAllPObj",doRemAllPObj;
GetDataVal "c"+ValToStr(CnvNum)+"DropWObj",doDropWObj;
GetDataVal "c"+ValToStr(CnvNum)+"PosInJobQ",doPosInJobQ;
GetDataVal "c"+ValToStr(CnvNum)+"NewObjStrobe",diNewObjStrobe;
GetDataVal "doManSync"+ValToStr(CnvNum),doManSync;
GetDataVal "c"+ValToStr(CnvNum)+"Count1FromEnc",giCount1FromEnc;
GetDataVal "c"+ValToStr(CnvNum)+"Count2FromEnc",giCount2FromEnc;
GetDataVal "c"+ValToStr(CnvNum)+"Count1ToEnc",goCount1ToEnc;
GetDataVal "c"+ValToStr(CnvNum)+"Count2ToEnc",goCount2ToEnc;
GetDataVal "c"+ValToStr(CnvNum)+"ForceJob",doForceJob;
GetDataVal "c"+ValToStr(CnvNum)+"CountToEncStr",doCountToEncStr;
SetDataSearch "mecunit"\Object:=CnvName;
IF GetNextSym(CnvMecString,block) THEN
GetDataVal CnvMecString\Block:=block,CnvMecUnit;
ELSE
ErrWrite "UNKNOWN CONVEYOR",CnvName\RL2:="is an unknown conveyor name. Look in"\RL3:="the S4 MOC configuration file for"\RL4:="valid conveyor names.";
Stop;
ENDIF
WorkObject.ufmec:=CnvName;
WorkObject.ufprog:=FALSE;
TPWrite "DELETING OBJECTS FROM CNV"+ValToStr(CnvNum);
NewObjReported:=FALSE;
IDelete NewObj;
SetDO doRemAllPObj,0;
SetDO doDropWObj,0;
WaitTime 0.5;
PulseDO doRemAllPObj;
WaitTime 0.5;
PulseDO doDropWObj;
WaitTime 0.5;
SetDO doPosInJobQ,1;
ActUnit CnvMecUnit;
WaitTime 0.5;
DropWObj WorkObject;
WaitTime 0.5;
!
TPWrite "WAITING FOR TRAP ON CNV"+ValToStr(CnvNum);
CONNECT NewObj WITH ObjTrap;
ISignalDI diNewObjStrobe,1,NewObj;
PulseDO doManSync;
WaitUntil NewObjReported=TRUE;
SetSysData Gripper;
SetSysData WorkObject;
TPWrite "CNV"+ValToStr(CnvNum)+" READY FOR CALIB";
WaitTime 3;
ELSEIF NonCnvWobjName<>"" OR CalibType=5 THEN
IF RemoteMode=0 THEN
TPWrite "Vision to robot calibration.";
TPReadFK IndNum,"Choose WorkObject","IdxWobj1","IdxWobj2","IdxWobj3","IdxWobj4","MORE";
IF IndNum=5 THEN
TPReadFK IndNum,"Choose WorkObject","IdxWobj5","IdxWobj6","IdxWobj7","IdxWobj8","";
IndNum:=IndNum+4;
ENDIF
NonCnvWobjName:="IdxWobj"+ValToStr(IndNum);
ELSE
TEST NonCnvWobjName
CASE "IdxWobj1":
IndNum:=1;
CASE "IdxWobj2":
IndNum:=2;
CASE "IdxWobj3":
IndNum:=3;
CASE "IdxWobj4":
IndNum:=4;
CASE "IdxWobj5":
IndNum:=5;
CASE "IdxWobj6":
IndNum:=6;
CASE "IdxWobj7":
IndNum:=7;
CASE "IdxWobj8":
IndNum:=8;
ENDTEST
ENDIF
SetSysData Gripper;
SetSysData WorkObject;
TPWrite "DEFINE CURRENT WORKOBJECT";
TPWrite " ";
TPWrite "CONTINUE RAPID EXECUTION WHEN READY";
TPWrite "TO SAVE THE NEW WORKOBJECT DEFINITION";
WaitTime 2;
Stop;
TPWrite " ";
TPReadFK ConfirmSave,"DO YOU WANT TO SAVE THIS WOBJ DEF?","","","","Yes","No";
IF ConfirmSave=4 THEN
FOR i FROM 1 TO MaxNoSources DO
IF NonCnvWOData{i}.NonCnvWobjName=NonCnvWobjName THEN
NonCnvWOData{i}.Used:=TRUE;
NonCnvWOData{i}.Wobj:=WorkObject;
ENDIF
ENDFOR
Save "PPASYS"\File:="ppasys.sys";
ENDIF
ENDIF
ENDPROC
!======================== ObjTrap =========================
TRAP ObjTrap
TPWrite "READING/COPYING ENC COUNTERS FOR CNV"+ValToStr(CnvNum);
ObjectPosition1:=GInput(giCount1FromEnc);
ObjectPosition2:=GInput(giCount2FromEnc);
WaitTime 0.2;
SetGO goCount1ToEnc,ObjectPosition1;
SetGO goCount2ToEnc,ObjectPosition2;
WaitTime 0.2;
PulseDO doForceJob;
PulseDO doCountToEncStr;
NewObjReported:=TRUE;
RETURN;
ENDTRAP
ENDMODULE
%%%
VERSION:1
LANGUAGE:ENGLISH
%%%
MODULE PPASYS(SYSMODULE,NOSTEPIN)
!***********************************************************
!
! Module: PPASYS
!
! $Revision: 1.5 $
!
! Description
! This is the additional system module for a pick and
! place application.
!
! Copyright (c) ABB Automation Technology Products 2002.
! All rights reserved
!
!***********************************************************
!
! Record datatype to hold datas which is specific for one work area.
! New data can be added to this record, but DO NOT delete any!
!
RECORD sourcedata
bool Used;
itmsrc ItemSource;
itmsrcinstdat SourceInstDat;
itmsrctype SourceType;
triggdata Ack;
triggdata Nack;
triggdata VacuumAct1;
triggdata VacuumAct2;
triggdata VacuumRev1;
triggdata VacuumRev2;
triggdata VacuumOff1;
triggdata VacuumOff2;
wobjdata Wobj;
num VacActDelay;
num VacRevDelay;
num VacOffDelay;
pos TunePos;
stoppointdata TrackPoint;
num OffsZ;
ENDRECORD
!
! Record datatype to hold indexed or fixed workarea datas which is
! specific for a work area.
! This is used instead of the baseframe calibrations for conveyors,
! which is stored in cfg, when a indexed or fixed workarea is used.
!
RECORD noncnvwobjdata
bool Used;
string NonCnvWobjName;
wobjdata Wobj;
ENDRECORD
CONST num MaxNoSources:=8;
VAR sourcedata ItmSrcData{MaxNoSources};
!
! Array for holding the non conveyor workobject data i.e. this is
! used instead of the baseframe configurations for the conveyors.
!
PERS noncnvwobjdata NonCnvWOData{MaxNoSources}:=[[FALSE,"IdxWobj1",[FALSE,TRUE,"",[[0,0,0],[1,0,0,0]],[[0,0,0],[1,0,0,0]]]],[FALSE,"IdxWobj2",[FALSE,TRUE,"",[[0,0,0],[1,0,0,0]],[[0,0,0],[1,0,0,0]]]],[FALSE,"IdxWobj3",[FALSE,TRUE,"",[[0,0,0],[1,0,0,0]],[[0,0,0],[1,0,0,0]]]],[FALSE,"IdxWobj4",[FALSE,TRUE,"",[[0,0,0],[1,0,0,0]],[[0,0,0],[1,0,0,0]]]],[FALSE,"IdxWobj5",[FALSE,TRUE,"",[[0,0,0],[1,0,0,0]],[[0,0,0],[1,0,0,0]]]],[FALSE,"IdxWobj6",[FALSE,TRUE,"",[[0,0,0],[1,0,0,0]],[[0,0,0],[1,0,0,0]]]],[FALSE,"IdxWobj7",[FALSE,TRUE,"",[[0,0,0],[1,0,0,0]],[[0,0,0],[1,0,0,0]]]],[FALSE,"IdxWobj8",[FALSE,TRUE,"",[[0,0,0],[1,0,0,0]],[[0,0,0],[1,0,0,0]]]]];
! Init and tuning variables
PERS num TuneType:=0;
CONST num SPEED_TUNE:=1;
CONST num PICKPLACE_TUNE:=2;
CONST num POS_TUNE:=3;
PERS string RemoteIPNode:="";
PERS string ItmSrcName:="";
PERS string CnvName:="";
PERS string NonCnvWobjName:="";
PERS itmsrctype SourceType:=0;
PERS num SourceIndex:=0;
PERS num VacActDelay:=0.02;
PERS num VacRevDelay:=0.02;
PERS num VacOffDelay:=0;
PERS num TunePosX:=0;
PERS num TunePosY:=0;
PERS num TunePosZ:=0;
PERS num FollowTime:=0.035;
PERS num OffsZ:=60;
! Return data to remote PC
PERS num ItmSrcId:=0;
PERS itmsrcinstdat SourceInstDat:=["",0];
! Accumulated number of actual picks
CONST num PickRateTime:=10;
CONST num NumOfPickToCalc:=6;
PERS num PicksPerMin:=0;
PERS num Picks:=0;
VAR num OldPicks:=0;
VAR num PickRateCount:=0;
VAR num NumOfPicksArr{NumOfPickToCalc}:=[0,0,0,0,0,0];
VAR intnum PickRateInt;
VAR intnum PickTuneInt;
PERS string RoutineName:="";
PERS bool ClearAllExecuted:=FALSE;
PERS bool SafeStopExecuted:=FALSE;
PERS bool PickPlaceRunning:=FALSE;
PERS bool WaitForExeOrder:=FALSE;
PERS bool FirstTime:=TRUE;
PERS bool InCoordRout:=FALSE;
PERS bool StopProcess:=FALSE;
VAR intnum SafeStopSignal;
VAR errnum PPA_JUMP_MOVE:=-1;
! AckDelay should be <= 0
VAR num AckDelay:=0;
PERS speeddata MaxSpeed:=[10000,10000,10000,10000];
PERS speeddata LowSpeed:=[3300,3500,10000,10000];
PERS speeddata VeryLowSpeed:=[250,3500,10000,10000];
PERS num Vtcp:=10000;
PERS num ITMSRC_QL0:=0;
PERS num ITMSRC_QL1:=0;
PERS num ITMSRC_QL2:=0;
PERS num ITMSRC_QL3:=0;
PERS num ITMSRC_QL4:=0;
PERS num ITMSRC_QL5:=0;
PERS num ITMSRC_QL6:=0;
PERS num ITMSRC_QL7:=0;
PERS num ITMSRC_QL8:=0;
PERS num ITMSRC_QL9:=0;
PERS num ITMSRC_QL10:=0;
PERS num ITMSRC_QL11:=0;
PERS num ITMSRC_QL12:=0;
PERS num ITMSRC_QL13:=0;
PERS num ITMSRC_QL14:=0;
PERS num ITMSRC_QL15:=0;
PERS num ITMSRC_QL16:=0;
PERS num ITMSRC_QL17:=0;
PERS num ITMSRC_QL18:=0;
PERS num ITMSRC_QL19:=0;
PERS num ITMSRC_QL20:=0;
PERS num ITMSRC_QL21:=0;
PERS num ITMSRC_QL22:=0;
PERS num ITMSRC_QL23:=0;
PERS num ITMSRC_QL24:=0;
PERS num ITMSRC_QL25:=0;
PERS num ITMSRC_QL26:=0;
PERS num ITMSRC_QL27:=0;
PERS num ITMSRC_QL28:=0;
PERS num ITMSRC_QL29:=0;
PERS num ITMSRC_QL30:=0;
PERS num ITMSRC_QL31:=0;
PERS num ITMSRC_QL32:=0;
PERS num ITMSRC_QL33:=0;
PERS num ITMSRC_QL34:=0;
PERS num ITMSRC_QL35:=0;
PERS num ITMSRC_QL36:=0;
PERS num ITMSRC_QL37:=0;
PERS num ITMSRC_QL38:=0;
PERS num ITMSRC_QL39:=0;
PERS num ITMSRC_QL40:=0;
PERS num ITMSRC_QL41:=0;
PERS num ITMSRC_QL42:=0;
PERS num ITMSRC_QL43:=0;
PERS num ITMSRC_QL44:=0;
PERS num ITMSRC_QL45:=0;
PERS num ITMSRC_QL46:=0;
PERS num ITMSRC_QL47:=0;
PERS num ITMSRC_QL48:=0;
PERS num ITMSRC_QL49:=0;
PERS num ITMSRC_QL50:=0;
PERS num ITMSRC_QW0:=0;
PERS num ITMSRC_QW1:=0;
PERS num ITMSRC_QW2:=0;
PERS num ITMSRC_QW3:=0;
PERS num ITMSRC_QW4:=0;
PERS num ITMSRC_QW5:=0;
PERS num ITMSRC_QW6:=0;
PERS num ITMSRC_QW7:=0;
PERS num ITMSRC_QW8:=0;
PERS num ITMSRC_QW9:=0;
PERS num ITMSRC_QW10:=0;
PERS num ITMSRC_QW11:=0;
PERS num ITMSRC_QW12:=0;
PERS num ITMSRC_QW13:=0;
PERS num ITMSRC_QW14:=0;
PERS num ITMSRC_QW15:=0;
PERS num ITMSRC_QW16:=0;
PERS num ITMSRC_QW17:=0;
PERS num ITMSRC_QW18:=0;
PERS num ITMSRC_QW19:=0;
PERS num ITMSRC_QW20:=0;
PERS num ITMSRC_QW21:=0;
PERS num ITMSRC_QW22:=0;
PERS num ITMSRC_QW23:=0;
PERS num ITMSRC_QW24:=0;
PERS num ITMSRC_QW25:=0;
PERS num ITMSRC_QW26:=0;
PERS num ITMSRC_QW27:=0;
PERS num ITMSRC_QW28:=0;
PERS num ITMSRC_QW29:=0;
PERS num ITMSRC_QW30:=0;
PERS num ITMSRC_QW31:=0;
PERS num ITMSRC_QW32:=0;
PERS num ITMSRC_QW33:=0;
PERS num ITMSRC_QW34:=0;
PERS num ITMSRC_QW35:=0;
PERS num ITMSRC_QW36:=0;
PERS num ITMSRC_QW37:=0;
PERS num ITMSRC_QW38:=0;
PERS num ITMSRC_QW39:=0;
PERS num ITMSRC_QW40:=0;
PERS num ITMSRC_QW41:=0;
PERS num ITMSRC_QW42:=0;
PERS num ITMSRC_QW43:=0;
PERS num ITMSRC_QW44:=0;
PERS num ITMSRC_QW45:=0;
PERS num ITMSRC_QW46:=0;
PERS num ITMSRC_QW47:=0;
PERS num ITMSRC_QW48:=0;
PERS num ITMSRC_QW49:=0;
PERS num ITMSRC_QW50:=0;
!***********************************************************
!
! Procedure ResetEvent
!
!***********************************************************
PROC ResetEvent()
InCoordRout:=FALSE;
ENDPROC
!***********************************************************
!
! Procedure PowerOnEvent
!
!***********************************************************
PROC PowerOnEvent()
BookErrNo PPA_JUMP_MOVE;
ENDPROC
!***********************************************************
!
! Procedure StopEvent
!
!***********************************************************
PROC StopEvent()
IF InCoordRout=TRUE THEN
WaitTime 2;
ClearPath;
ENDIF
ENDPROC
!***********************************************************
!
! Procedure RestartEvent
!
!***********************************************************
PROC RestartEvent()
IF PPA_JUMP_MOVE=-1 THEN
BookErrNo PPA_JUMP_MOVE;
ENDIF
IF InCoordRout=TRUE THEN
RAISE PPA_JUMP_MOVE;
ENDIF
ERROR
IF InCoordRout=TRUE THEN
InCoordRout:=FALSE;
RAISE;
ENDIF
ENDPROC
!***********************************************************
!
! Procedure NewSource
!
! This procedure is called from the routines
! picknew/placenew which is called by PickMaster.
! Since RobCom does not support parameter passing when
! running a procedure the parameters are passed via PERS
! variables prior to call and possible results returned
! the same way.
! 0 or empty string indicates that parameter is not used
!
! The following "call parameters" are used:
! IN:
! string CnvName
! string NonCnvWobjName
! string ItmSrcName
! itmsrctype SourceType
! num SourceIndex
! OUT:
! itmsrcinstdat InstDat
!
!
!***********************************************************
PROC NewSource()
VAR bool Found;
VAR mecunit CnvMecUnit;
VAR string CnvMecString;
VAR datapos block;
VAR itmsrc ItemSource;
ItmSrcData{SourceIndex}.Wobj:=wobj0;
TPWrite ItmSrcName;
! Create an item source
NewItmSrc ItemSource,ItmSrcName;
IF CnvName<>"" THEN
SetDataSearch "mecunit"\Object:=CnvName;
IF GetNextSym(CnvMecString,block) THEN
GetDataVal CnvMecString\Block:=block,CnvMecUnit;
ActUnit CnvMecUnit;
ItmSrcData{SourceIndex}.Wobj.ufmec:=CnvName;
ItmSrcData{SourceIndex}.Wobj.ufprog:=FALSE;
ELSE
ErrWrite "Unknown conveyor ",CnvName\RL2:=" is an unknown conveyor name. Look in"\RL3:="the S4 MOC configuration file for"\RL4:="valid conveyor names (PPA/placenew).";
Stop;
ENDIF
ELSEIF NonCnvWobjName<>"" THEN
Found:=FALSE;
FOR i FROM 1 TO MaxNoSources DO
IF NonCnvWOData{i}.Used THEN
IF NonCnvWOData{i}.NonCnvWobjName=NonCnvWobjName THEN
Found:=TRUE;
ItmSrcData{SourceIndex}.Wobj:=NonCnvWOData{i}.Wobj;
ENDIF
ENDIF
ENDFOR
IF Found=FALSE THEN
ErrWrite "Unknown userframe ",NonCnvWobjName\RL2:=" is an unknown frame name";
Stop;
ENDIF
ENDIF
ItmSrcData{SourceIndex}.Used:=TRUE;
CreateInstDat ItemSource,SourceInstDat;
ItmSrcData{SourceIndex}.SourceInstDat:=SourceInstDat;
ItmSrcByName ItmSrcData{SourceIndex}.ItemSource,ItmSrcData{SourceIndex}.SourceInstDat.Name;
ItmSrcData{SourceIndex}.SourceType:=SourceType;
ItmSrcData{SourceIndex}.VacActDelay:=VacActDelay;
ItmSrcData{SourceIndex}.VacRevDelay:=VacRevDelay;
ItmSrcData{SourceIndex}.VacOffDelay:=VacOffDelay;
ItmSrcData{SourceIndex}.TunePos:=[TunePosX,TunePosY,TunePosZ];
ItmSrcData{SourceIndex}.OffsZ:=OffsZ;
IF CnvName<>"" THEN
ItmSrcData{SourceIndex}.TrackPoint:=[fllwtime,FALSE,[0,0,0,0],0,FollowTime,"",0,0];
ELSEIF NonCnvWobjName<>"" THEN
ItmSrcData{SourceIndex}.TrackPoint:=[stoptime,FALSE,[0,0,0,0],FollowTime,0,"",0,0];
ENDIF
TriggEquip ItmSrcData{SourceIndex}.Ack,0,AckDelay\ProcID:=ItmSrcData{SourceIndex}.SourceInstDat.Id,ITMSRC_ACKENTRY;
TriggEquip ItmSrcData{SourceIndex}.Nack,0,AckDelay\ProcID:=ItmSrcData{SourceIndex}.SourceInstDat.Id,ITMSRC_NACKENTRY;
ItmSrcId:=ItmSrcData{SourceIndex}.SourceInstDat.Id;
IF RemoteIPNode<>"" THEN
SCWrite\ToNode:=RemoteIPNode,ItmSrcId;
ENDIF
ExitCycle;
ERROR
IF ERRNO=ERR_ITMSRC_UNDEF THEN
TRYNEXT;
ELSEIF ERRNO=ERR_SC_WRITE THEN
TRYNEXT;
ELSE
RAISE;
ENDIF
ENDPROC
!***********************************************************
!
! Procedure ClearAll
!
! Clean the environnement in order to restart the application
! with a known status.
!
! In order to achieve this, one has to reextract the associated
! non-value date types because these are declared as variables
! (i.e. their value will be lost if we move PP to execute the
! present procedure). To be able to extract these non-value data
! one associates PERS variables to keep track of the allocations.
!
!***********************************************************
PROC ClearAll()
VAR num Index;
VAR mecunit CnvMecUnit;
VAR string CnvMecString;
VAR datapos block;
TPWrite "ClearAll";
! Reset variables
ClearAllExecuted:=FALSE;
SafeStopExecuted:=FALSE;
PickPlaceRunning:=FALSE;
WaitForExeOrder:=FALSE;
FirstTime:=TRUE;
InCoordRout:=FALSE;
StopProcess:=FALSE;
IDelete PickTuneInt;
PickRateReset;
! Reset trap signal
Reset doSafeStop;
! Free the item sources and the mechanical units.
FreeAllItmSrc;
FOR Index FROM 1 TO MaxNoSources DO
IF (ItmSrcData{Index}.Wobj.ufmec<>"") THEN
SetDataSearch "mecunit"\Object:=ItmSrcData{Index}.Wobj.ufmec;
IF GetNextSym(CnvMecString,block) THEN
GetDataVal CnvMecString\Block:=block,CnvMecUnit;
DeactUnit CnvMecUnit;
ItmSrcData{Index}.Wobj:=wobj0;
ELSE
ErrWrite "Unknown conveyor ",ItmSrcData{Index}.Wobj.ufmec\RL2:=" is an unknown place conveyor"\RL3:="(PPA/ClearAll).";
Stop;
ENDIF
ELSE
ItmSrcData{Index}.Wobj:=wobj0;
ENDIF
ItmSrcData{Index}.Used:=FALSE;
ENDFOR
ClearAllExecuted:=TRUE;
IF RemoteIPNode<>"" THEN
SCWrite\ToNode:=RemoteIPNode,ClearAllExecuted;
ENDIF
TPWrite "ClearAll executed";
ExitCycle;
ERROR
IF ERRNO=ERR_ITMSRC_UNDEF THEN
TRYNEXT;
ELSEIF ERRNO=ERR_SC_WRITE THEN
TRYNEXT;
ELSE
RAISE;
ENDIF
ENDPROC
!***********************************************************
!
! Procedure PickRateInit
!
!***********************************************************
PROC PickRateInit()
PickRateReset;
CONNECT PickRateInt WITH PickRateTrap;
ITimer PickRateTime,PickRateInt;
ENDPROC
!***********************************************************
!
! Procedure PickRateReset
!
!***********************************************************
PROC PickRateReset()
Picks:=0;
PicksPerMin:=0;
PickRateCount:=0;
FOR i FROM 1 TO NumOfPickToCalc DO
NumOfPicksArr{i}:=0;
ENDFOR
IDelete PickRateInt;
ENDPROC
!***********************************************************
!
! Procedure WalkTheData
!
!***********************************************************
PROC WalkTheData()
VAR iodev logfile;
Open "HOME:"\File:="TheData.log",logfile\Write;
Write logfile,"ItmSrcData";
FOR i FROM 1 TO MaxNoSources DO
Write logfile,"Index: "\Num:=i;
Write logfile,"Used: "\Bool:=ItmSrcData{i}.Used;
Write logfile,"ItmSrc Name: "+ItmSrcData{i}.SourceInstDat.Name;
Write logfile,"ItmSrc Id: "\Num:=ItmSrcData{i}.SourceInstDat.Id;
Write logfile,"ItmSrcType: "\Num:=ItmSrcData{i}.SourceType;
Write logfile,"ufmec: "+ItmSrcData{i}.Wobj.ufmec;
Write logfile,"VacActDelay: "\Num:=ItmSrcData{i}.VacActDelay;
Write logfile,"VacRevDelay: "\Num:=ItmSrcData{i}.VacRevDelay;
Write logfile,"VacOffDelay: "\Num:=ItmSrcData{i}.VacOffDelay;
Write logfile,"TunePos x: "\Num:=ItmSrcData{i}.TunePos.x;
Write logfile,"TunePos y: "\Num:=ItmSrcData{i}.TunePos.y;
Write logfile,"TunePos z: "\Num:=ItmSrcData{i}.TunePos.z;
IF ItmSrcData{i}.TrackPoint.type=fllwtime THEN
Write logfile,"Followtime: "\Num:=ItmSrcData{i}.TrackPoint.followtime;
ELSEIF ItmSrcData{i}.TrackPoint.type=stoptime THEN
Write logfile,"Stoptime: "\Num:=ItmSrcData{i}.TrackPoint.stoptime;
ENDIF
Write logfile,"OffsZ: "\Num:=ItmSrcData{i}.OffsZ;
Write logfile," ";
ENDFOR
Write logfile,"NonCnvWOData";
FOR i FROM 1 TO MaxNoSources DO
Write logfile,"Index: "\Num:=i;
Write logfile,"Used: "\Bool:=NonCnvWOData{i}.Used;
Write logfile,"Name: "+NonCnvWOData{i}.NonCnvWobjName;
Write logfile,"uframe.trans.x: "\Num:=NonCnvWOData{i}.Wobj.uframe.trans.x;
Write logfile,"uframe.trans.y: "\Num:=NonCnvWOData{i}.Wobj.uframe.trans.y;
Write logfile,"uframe.trans.z: "\Num:=NonCnvWOData{i}.Wobj.uframe.trans.z;
Write logfile," ";
ENDFOR
Close logfile;
ENDPROC
!***********************************************************
!
! Function GetQueueLevel
!
! This function return the current level of the item source.
! The function will return -1 if the function fails.
!
! The following "call parameters" are used:
! IN:
! num Index
! OUT:
! num QueueLevel
!
!***********************************************************
FUNC num GetQueueLevel(
num Index)
VAR datapos SearchBlock;
VAR string Name:="";
VAR string VarName:="";
VAR num QueueLevel:=-1;
VarName:="ITMSRC_QL"+ValToStr(ItmSrcData{Index}.SourceInstDat.Id);
SetDataSearch "num"\Object:=VarName\InMod:="PPASYS";
IF GetNextSym(Name,SearchBlock\Recursive) THEN
GetDataVal Name\Block:=SearchBlock,QueueLevel;
ENDIF
RETURN QueueLevel;
ENDFUNC
!***********************************************************
!
! Function GetQueueTopLevel
!
! This function return the highest level of the item source.
! The function will return -1 if the function fails.
!
! The following "call parameters" are used:
! IN:
! num Index
! OUT:
! num QueueLevel
!
!***********************************************************
FUNC num GetQueueTopLevel(
num Index)
VAR datapos SearchBlock;
VAR string Name:="";
VAR string VarName:="";
VAR num TopLevel:=-1;
VarName:="ITMSRC_QW"+ValToStr(ItmSrcData{Index}.SourceInstDat.Id);
SetDataSearch "num"\Object:=VarName\InMod:="PPASYS";
IF GetNextSym(Name,SearchBlock\Recursive) THEN
GetDataVal Name\Block:=SearchBlock,TopLevel;
ENDIF
RETURN TopLevel;
ENDFUNC
!**********************************************************
!
! Trap PickRateTrap
!
!**********************************************************
TRAP PickRateTrap
VAR num NumOfValuesInArr;
VAR num PickSum;
IF (Picks>(8388608-1000)) OR (PickRateCount>=8388608) THEN
Picks:=0;
OldPicks:=0;
PicksPerMin:=0;
PickRateCount:=0;
FOR i FROM 1 TO NumOfPickToCalc DO
NumOfPicksArr{i}:=0;
ENDFOR
ELSE
Incr PickRateCount;
IF (PickRateCount<NumOfPickToCalc) THEN
NumOfValuesInArr:=PickRateCount;
ELSE
NumOfValuesInArr:=NumOfPickToCalc;
ENDIF
FOR i FROM (NumOfPickToCalc-1) TO 1 DO
NumOfPicksArr{i+1}:=NumOfPicksArr{i};
ENDFOR
NumOfPicksArr{1}:=Picks-OldPicks;
OldPicks:=Picks;
FOR i FROM 1 TO NumOfPickToCalc DO
PickSum:=PickSum+NumOfPicksArr{i};
ENDFOR
PicksPerMin:=Round((PickSum)/(NumOfValuesInArr*PickRateTime/60));
ENDIF
IF RemoteIPNode<>"" THEN
SCWrite\ToNode:=RemoteIPNode,Picks;
SCWrite\ToNode:=RemoteIPNode,PicksPerMin;
ENDIF
ERROR
IF ERRNO=ERR_SC_WRITE THEN
TRYNEXT;
ENDIF
ENDTRAP
ENDMODULE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment