I have a procedure in IRC5 RW6, where a SearchL instruction is used.
SearchL\Stop, diSearch\NegFlank, pRobFound, pRobEnd, v10, tGripper\WObj:=wobj1;
The documentation in the help is not completely clear to me.
If the signal diSearch is already low when the instruction SearchL is called, will an error ERR_SIGSUPSEARCH
be generated? Or will the search movement go through until pRobEnd is reached.
If the ERR_SIGSUPSEARCH would be generated, and there is an error handler at the bottom of the procedure, but the code in the error handler is empty, what will happen then?
Error handler
- Plc_User
- Thread is marked as Resolved.
-
-
If the signal diSearch is already low when the instruction SearchL is called, will an error ERR_SIGSUPSEARCH
be generated?
NO, because you are using Flanks optional argument. It reacts on the falling edge of the signal, so it must see the change of state from HIGH to LOW.
Or will the search movement go through until pRobEnd is reached.
In this case, YES.
If the ERR_SIGSUPSEARCH would be generated, and there is an error handler at the bottom of the procedure, but the code in the error handler is empty, what will happen then?
Cotrol will pass to the system error handler if the end of the routine error handler is reached.
Within the error handler you would do something like:Test ERRNO
CASE ERR_SIGSUPSEARCH:
! Do something here like move back to search start position or modify it somehow
DEFAULT
Stop;
! check the value of ERRNO to determine the cause of error so you can fix it
EndTest -
Lemster,
Thanks for the info.W
The code is however now in a robot in production (installation from other manufacturer) and we don't have acces to it just now.
What will exactly happen in the cycle if the error handler is called but nothing is done in it?
Will the robot stop?
And will the instruction as is actually in the robot generate the error ERR_SIGSUPSEARCH if the instruction is called when the digital input is already low before?
SearchL\Stop, diSearch\NegFlank, pRobFound, pRobEnd, v10, tGripper\WObj:=wobj1;
It is not completely clear to me from the help is with these arguments the ERR_SIGSUPSEARCH is generated.Thanks
-
Yes, it should stop when the error is transferred to the system error handler. No, it should not generate that error if the signal is already low when the search begins.
-
Thanks !
-
SearchL is a very rough tool, it lacks the finesse you need many times.
You're better off using/writing your own search routine/instruction with an error handler built in (Smartac for example) which handles all the issues / errors for you. I've attached an old file that I used to use back in the day.
As an example, what it does is that it runs through an init cycle and if there's contact from the start it backs out a few mm to retry and it keeps doing that a few times until it either fails (throws an error) or clears the part (start the search).
Code
Display More%%% VERSION:1 LANGUAGE:ENGLISH %%% MODULE SMARTAC(SYSMODULE, NOVIEW) CONST errnum erSMARTAC_INIT:=10; CONST errnum erFALSE_STOP:=11; LOCAL CONST string stSearchErr:="INVALID search sequence"; LOCAL VAR string stReason; LOCAL CONST string stPDispInfo:="Current PDisp is deleted"; LOCAL CONST string stPPInfo:="Check program line before Start"; LOCAL CONST num DEFAULT_MAX_CORR:=3; LOCAL CONST num DEFAULT_MAX_WAIT:=2; LOCAL CONST num DEFA_HIGH_NEEDED:=1; LOCAL CONST num DEFA_MAX_CYCLES:=10; LOCAL CONST num DEFA_CYCL_TIME:=0.001; VAR bool smaDebug; !------------------------------------------------------------------------------------------ !------ ! Added Optional Switch "|INOUT pose Result" and "\pose PrePDisp" (X.X./X.X.) !------ PROC smaSearchL( \switch NoPdispOn |INOUT pose Result \switch WireSearch, robtarget pStartPredef, robtarget pSearchPredef, num nEndDist, num nReturnDist, speeddata vTravel, speeddata vSearch, PERS tooldata Tool \PERS wobjdata WObj \pose PrePDisp \num MyCorrStepNumb \num MyWaitForValid \num MyHighNeeded \num MyMaxCyclesCheck \num MyCycleTimeCheck) VAR num nMaxCorrStepNumb; VAR num nMaxWaitForValid; VAR num nHighNeeded; VAR num nMaxCyclesCheck; VAR num nCycleTimeCheck; AWLog\SearchModeOn; IF Present(MyCorrStepNumb) THEN nMaxCorrStepNumb:=MyCorrStepNumb; ELSE nMaxCorrStepNumb:=DEFAULT_MAX_CORR; ENDIF IF Present(MyWaitForValid) THEN nMaxWaitForValid:=MyWaitForValid; ELSE nMaxWaitForValid:=DEFAULT_MAX_WAIT; ENDIF IF Present(MyHighNeeded) THEN nHighNeeded:=MyHighNeeded; ELSE nHighNeeded:=DEFA_HIGH_NEEDED; ENDIF IF Present(MyMaxCyclesCheck) THEN nMaxCyclesCheck:=MyMaxCyclesCheck; ELSE nMaxCyclesCheck:=DEFA_MAX_CYCLES; ENDIF IF Present(MyCycleTimeCheck) THEN nCycleTimeCheck:=MyCycleTimeCheck; ELSE nCycleTimeCheck:=DEFA_CYCL_TIME; ENDIF IF Present(WireSearch) THEN SMAloc_SearchL\NoPdispOn?NoPdispOn\Result?Result,doSE2_SEL,diSE2_DET,pStartPredef,pSearchPredef,nEndDist,nReturnDist,vTravel,vSearch,Tool\WObj?WObj\PrePDisp?PrePDisp,nMaxCorrStepNumb,nMaxWaitForValid,nHighNeeded,nMaxCyclesCheck,nCycleTimeCheck; ELSE SMAloc_SearchL\NoPdispOn?NoPdispOn\Result?Result,doSE1_SEL,diSE1_DET,pStartPredef,pSearchPredef,nEndDist,nReturnDist,vTravel,vSearch,Tool\WObj?WObj\PrePDisp?PrePDisp,nMaxCorrStepNumb,nMaxWaitForValid,nHighNeeded,nMaxCyclesCheck,nCycleTimeCheck; ENDIF AWLog\SearchModeOff; ERROR IF ERRNO=erFALSE_STOP THEN RETRY; ENDIF RAISE; ENDPROC PROC SMA_SearchL( \switch Pdisp \switch INIT \switch NoBreakBox, robtarget pStartPredef, robtarget pSearchPredef, num nEndDist, num nReturnDist, speeddata vTravel, speeddata vSearch, num CorrStepNumb, PERS tooldata Tool \PERS wobjdata WObj) VAR num nMaxCorrStepNumb; VAR num nMaxWaitForValid; VAR num nHighNeeded; VAR num nMaxCyclesCheck; VAR num nCycleTimeCheck; AWLog\SearchModeOn; nMaxCorrStepNumb:=CorrStepNumb; nMaxWaitForValid:=DEFAULT_MAX_WAIT; nHighNeeded:=DEFA_HIGH_NEEDED; nMaxCyclesCheck:=DEFA_MAX_CYCLES; nCycleTimeCheck:=DEFA_CYCL_TIME; IF Present(PDISP) THEN SMAloc_SearchL doSE1_SEL,diSE1_DET,pStartPredef,pSearchPredef,nEndDist,nReturnDist,vTravel,vSearch,Tool\WObj?WObj,nMaxCorrStepNumb,nMaxWaitForValid,nHighNeeded,nMaxCyclesCheck,nCycleTimeCheck; ELSE SMAloc_SearchL\NoPdispOn,doSE1_SEL,diSE1_DET,pStartPredef,pSearchPredef,nEndDist,nReturnDist,vTravel,vSearch,Tool\WObj?WObj,nMaxCorrStepNumb,nMaxWaitForValid,nHighNeeded,nMaxCyclesCheck,nCycleTimeCheck; ENDIF AWLog\SearchModeOff; ERROR IF ERRNO=erFALSE_STOP THEN RETRY; ENDIF RAISE; ENDPROC !------------------------------------------------------------------------------------------ !------ ! Added Optional Switch "|INOUT pose Result" and "\pose PrePDisp" (M.L./AS) !------ LOCAL PROC SMAloc_SearchL( \switch NoPdispOn |INOUT pose Result, VAR signaldo doSensorSelect, VAR signaldi diSensorDetect, robtarget pStartPredef, robtarget pSearchPredef, num nEndDist, num nReturnDist, speeddata vTravel, speeddata vSearch, PERS tooldata Tool \PERS wobjdata WObj \pose PrePDisp, num nMaxCorrStepNumb, num nMaxWaitForValid, num nHighNeeded, num nMaxCyclesCheck, num nCycleTimeCheck) VAR robtarget pSearchCurr; VAR robtarget pEndPrecalc; VAR robtarget pReturnCurr; VAR pos psUnitVect; VAR num nCorrStepNumb; !------ ! Added "IF Present(PrePdisp) THEN" (M.L./AS) !------ IF Present(PrePDisp) THEN pStartPredef:=addVect(pStartPredef,PrePDisp.trans); pSearchPredef:=addVect(pSearchPredef,PrePDisp.trans); ENDIF psUnitVect:=calcUnitVect(pSearchPredef.trans,pStartPredef.trans); pEndPrecalc:=addVect(pSearchPredef,nEndDist*psUnitVect); MoveL pStartPredef,vTravel,fine,Tool\WObj?WObj; WHILE NOT SMA_Init(doSensorSelect,diSensorDetect,nMaxWaitForValid,nMaxCyclesCheck,nCycleTimeCheck) DO Incr nCorrStepNumb; IF nCorrStepNumb<=nMaxCorrStepNumb THEN SMA_Off; pStartPredef:=subVect(pStartPredef,psUnitVect); MoveL pStartPredef,vTravel,fine,Tool\WObj?WObj; ErrWrite\W,"Smartac INIT warning","INIT retry will follow"\RL2:=" after a correction step."\RL3:="Object probably in contact before search."; IF smadebug TPWrite "Contact at search start"; ELSE RAISE erSMARTAC_INIT; ENDIF ENDWHILE SearchL\Stop,diSensorDetect,pSearchCurr,pEndPrecalc,vSearch,Tool\WObj?WObj; IF NOT TrueDetect(diSensorDetect,nHighNeeded,nMaxCyclesCheck,nCycleTimeCheck) THEN RAISE erFALSE_STOP; ENDIF SMA_Off; pReturnCurr:=subVect(pSearchCurr,nReturnDist*psUnitVect); MoveL pReturnCurr,vTravel,fine,Tool\WObj?WObj; IF NOT Present(NoPdispOn) THEN PDispOn\ExeP:=pSearchCurr,pSearchPredef,Tool\WObj?WObj; !------ ! Added "ELSEIF Present(Result) THEN" (M.L./AS) !------ ELSEIF Present(Result) THEN Result:=[[0,0,0],[1,0,0,0]]; Result.trans:=pSearchCurr.trans-pSearchPredef.trans; ENDIF ERROR SMA_Off; TEST ERRNO CASE erSMARTAC_INIT: stReason:="Init failed even after correction steps"; CASE erFALSE_STOP: ErrWrite\W,"Smartac search warning","Detect signal unstable"\RL2:="Search RETRY is performed"; CASE ERR_WHLSEARCH: stReason:="No search stop detected"; SkipWarn; CASE ERR_SIGSUPSEARCH: stReason:="Search stop detected already at start"; SkipWarn; DEFAULT: stReason:="A none-search error during searching"; ENDTEST IF ERRNO<>erFALSE_STOP THEN PDispOff; ErrWrite stSearchErr,stReason\RL2:=stPDispInfo\RL3:=stPPInfo; ENDIF RAISE; ENDPROC !............................................................... LOCAL FUNC bool TrueDetect( VAR signaldi diSensorDetect, num nHighNeeded, num nMaxCyclesCheck, num nCycleTimeCheck) VAR num nNumbOfHigh; FOR nCycle FROM 1 TO nMaxCyclesCheck DO WaitTime nCycleTimeCheck; IF TestDI(diSensorDetect) Incr nNumbOfHigh; IF nNumbOfHigh>=nHighNeeded THEN IF nNumbOfHigh<nCycle ErrWrite\W,"Smartac search warning","Detect signal unstable"\RL2:=" but accepted"; RETURN TRUE; ENDIF ENDFOR RETURN FALSE; ENDFUNC !............................................................... LOCAL FUNC bool GhostDetect( VAR signaldi diSensorDetect, num nMaxCyclesCheck, num nCycleTimeCheck) VAR num nNumbOfHigh; WaitTime 0.05; FOR nCycle FROM 1 TO nMaxCyclesCheck DO WaitTime nCycleTimeCheck; IF TestDI(diSensorDetect) Incr nNumbOfHigh; ENDFOR IF nNumbOfHigh>0 THEN ErrWrite\W,"SIGSUP warning",""; IF smadebug TPWrite "Num Ghost"\Num:=nNumbOfHigh; RETURN TRUE; ENDIF RETURN FALSE; ENDFUNC !............................................................... LOCAL FUNC bool SMA_Init( VAR signaldo doSensorSelect, VAR signaldi diSensorDetect, num nMaxWaitForValid, num nMaxCyclesCheck, num nCycleTimeCheck) VAR bool bTimeOut; ClkReset clock1; SMA_Off; ClkStart clock1; WaitDI diSE_VALID,low\MaxTime:=nMaxWaitForValid\TimeFlag:=bTimeOut; ClkStop clock1; IF smadebug TPWrite "S1: "\Num:=ClkRead(clock1); ClkReset clock1; IF bTimeOut RETURN FALSE; Set doSensorSelect; ClkStart clock1; WaitDI diSE_VALID,high\MaxTime:=nMaxWaitForValid\TimeFlag:=bTimeOut; ClkStop clock1; IF smadebug TPWrite "S2: "\Num:=ClkRead(clock1); ClkReset clock1; IF bTimeOut RETURN FALSE; Set doSE_REF; IF GhostDetect(diSensorDetect,nMaxCyclesCheck,nCycleTimeCheck) RETURN FALSE; IF smadebug TPWrite "S3"; RETURN TRUE; ENDFUNC !............................................................... LOCAL PROC SMA_Off() Reset doSE1_SEL; Reset doSE2_SEL; Reset doSE_REF; ENDPROC !............................................................... LOCAL FUNC pos calcUnitVect( pos psDest, pos psSource) VAR pos psVect; VAR num Len; Len:=Distance(psDest,psSource); psVect.x:=(psDest.x-psSource.x)/Len; psVect.y:=(psDest.y-psSource.y)/Len; psVect.z:=(psDest.z-psSource.z)/Len; RETURN psVect; ENDFUNC !............................................................... LOCAL FUNC robtarget addVect( robtarget pOrig, pos psCorrVect) VAR robtarget pCorr; pCorr:=pOrig; pCorr.trans.x:=pCorr.trans.x+psCorrVect.x; pCorr.trans.y:=pCorr.trans.y+psCorrVect.y; pCorr.trans.z:=pCorr.trans.z+psCorrVect.z; RETURN pCorr; ENDFUNC !............................................................... LOCAL FUNC robtarget subVect( robtarget pOrig, pos psCorrVect) VAR robtarget pCorr; pCorr:=pOrig; pCorr.trans.x:=pCorr.trans.x-psCorrVect.x; pCorr.trans.y:=pCorr.trans.y-psCorrVect.y; pCorr.trans.z:=pCorr.trans.z-psCorrVect.z; RETURN pCorr; ENDFUNC PROC smaSrchSQR( \switch PrePDisp \switch PDisp, robtarget srchStart \num SrchDist, speeddata TrvlSpeed, speeddata SrchSpeed, PERS tooldata Tool \PERS wobjdata WObj) VAR pos posSearchLen; VAR pose poseDisp; VAR robtarget pCirCent; VAR robtarget pC{4}; VAR num nYOffs; VAR num nSeamWidth; VAR num nSD; VAR num X{3}; VAR num Y{3}; VAR num Z{3}; VAR num nCupDia; IF Present(SrchDist) THEN nSD:=SrchDist; ELSE nSD:=50; ENDIF MoveL srchStart,TrvlSpeed,[TRUE,0,0,0,0,0,0],Tool\WObj?WObj; SmaSearchL\NoPdispOn,srchStart,Offs(srchStart,nSD,0,0),10,0,TrvlSpeed,SrchSpeed,Tool\WObj?WObj; WaitTime 0.1; pC{1}:=CRobT(\Tool:=Tool\WObj?WObj); MoveL Offs(pC{1},-5,0,0),TrvlSpeed,[FALSE,5,8,8,0.8,8,0.8],Tool\WObj?WObj; SmaSearchL\NoPdispOn,srchStart,Offs(srchStart,-nSD,0,0),10,0,TrvlSpeed,SrchSpeed,Tool\WObj?WObj; WaitTime 0.1; pC{2}:=CRobT(\Tool:=Tool\WObj?WObj); MoveL Offs(pC{2},5,0,0),TrvlSpeed,[FALSE,5,8,8,0.8,8,0.8],Tool\WObj?WObj; pCirCent:=srchStart; pCirCent.trans:=(pC{1}.trans+pC{2}.trans)*0.5; SmaSearchL\NoPdispOn,pCirCent,Offs(pCirCent,0,nSD,0),10,0,TrvlSpeed,SrchSpeed,Tool\WObj?WObj; WaitTime 0.1; pC{1}:=CRobT(\Tool:=Tool\WObj?WObj); MoveL Offs(pC{1},0,-5,0),TrvlSpeed,[FALSE,5,8,8,0.8,8,0.8],Tool\WObj?WObj; SmaSearchL\NoPdispOn,pCirCent,Offs(pCirCent,0,-nSD,0),10,0,TrvlSpeed,SrchSpeed,Tool\WObj?WObj; WaitTime 0.1; pC{2}:=CRobT(\Tool:=Tool\WObj?WObj); pCirCent.trans:=(pC{1}.trans+pC{2}.trans)*0.5; MoveL pCirCent,TrvlSpeed,[TRUE,0,0,0,0,0,0],Tool\WObj?WObj; poseDisp.trans:=(pCirCent.trans-srchStart.trans); poseDisp.rot:=[1,0,0,0]; IF Present(PrePDisp) poseDisp.trans:=poseDisp.trans+C_PROGDISP.pdisp.trans; IF Present(Pdisp) THEN PDispSet poseDisp; IF smadebug TPWrite "Result: "\Pos:=poseDisp.trans; ENDIF RETURN; ENDPROC ENDMODULE