Wait for condition in a subroutine
Simmu
✭
in RobotStudio
I'm trying to create an alternative WaitUntil routine, where I can perform certain tasks while waiting for specific conditions to be met.
I'm thinking the routine should look something like this:
I'm thinking the routine should look something like this:
VAR clock cTimerWait;
WHILE Cond=FALSE AND (Present(MaxTime)=FALSE OR clkRead(cTimerWait)<MaxTime) DO
WaitTime 0.05;
ClkStart cTimerWait;
!
! - DO OTHER STUFF - !
!
ENDWHILE
IF Cond=FALSE AND (Present(MaxTime)=TRUE AND clkRead(cTimerWait)>MaxTime) THEN
IF Present(TimeFlag)=TRUE THEN
TimeFlag:=TRUE;
RETURN ;
ELSE
RAISE ERR_WAIT_MAXTIME;
ENDIF
ENDIF
RETURN;
ENDPROC
PROC TestWaitUntil()
MyOwn_WaitUntil diSensor1=1\MaxTime:=5;
ENDPROC
The problem in this code is that the parameter "Cond" is not updating, i.e. if diSensor1 equals 0 when entering the routine the parameter Cond is set to FALSE and remains FALSE even when diSensor1 turns on.
Does anyone have suggestions on how to change this code to always get the actual state of "Cond"?
0
Comments
-
I'm not sure if it helps but have you tried INOUT ?
PROC MyOwn_WaitUntil(INOUT bool Cond\num MaxTime\INOUT bool TimeFlag)
Systemintegrator - Web / C# / Rapid / Robotstudio
If I helped, please press Vote Up
☑️2024 - RobotStudio® User Group0 -
I have tried both INOUT and VAR bool. They "work" in that sense the variable inside the routine is updated, but the input parameter must be one simple variable. It does not work with for example digital inputs or numerical comparisons.0
-
Make it a function. The TestDI function already exists for the datatype for Inputs, SignalDI.Lee Justice0
-
Hi ...For this to work correctly you must work with Alias associated with the entries you want.Here is an example:
PROC RobotHeating(string sAliasDIExecHeating) !######## VAR num presentDayL:=1; !######## ! Associate the Alias ... AliasIO sAliasDIExecHeating,aliasDiExecActionL; ! Wait if the signal is 0 ... IF (aliasDiExecActionL=1) THEN presentDayL:=GetTime(\WDay); ELSE IF aliasDiExecActionL=0 THEN WaitUntil aliasDiExecActionL=1; presentDayL:=GetTime(\WDay); ENDIF ENDIF ERROR TPErase; TEST ERRNO CASE ERR_ALIASIO_DEF: ErrWrite "ERR_ALIASIO_DEF","" EXIT; CASE ERR_ALIASIO_TYPE: RETRY; CASE ERR_NO_ALIASIO_DEF: RETRY; CASE ERR_OVERFLOW DEFAULT: Stop; ENDTEST ENDPROC
MODULE ModPRG() VAR string sAliasDIExecHeating; PROC main() sAliasDIExecHeating:="PLC_Rx_HeatingAx" RobotHeating sAliasDIExecHeating; ENDPROC ENDMODULE
'PLC_Rx_HeatingAx' is the name of the signal, as it is in the EIO.cfg fileI hope this helps.Good work.0 -
Simmu said:I have tried both INOUT and VAR bool. They "work" in that sense the variable inside the routine is updated, but the input parameter must be one simple variable. It does not work with for example digital inputs or numerical comparisons.
MODULE LEERULZ ! ! This module contains two routines, rEnter and rExit which are ! intended to be universal handshake routines for requesting ! entry from the cell controller to enter an area, fixture or ! robot interference zone. When called, the user must pass in ! the parameters and switches unique to the user's installation. ! I.E., Digital inputs and digital outputs from your IO map, your ! tool and workobjects, if used. Nothing is hard-coded, so there ! is no need to rewrite these routines for your particular ! project. Both routines have Backward handlers so the user will ! be able to step backwards through the procedure call. The robot ! will move back to where it came from using the parameter passed ! which should be the parameter robtarget or jointtarget from which ! it came when requesting entry or exit. Then It will set or reset ! the digital output for clear as appropriate to enter or exit. ! pass in the parameter for the path interpolation used, linear, joint ! or MoveAbsJ. Or, the default will be joint interpolation. ! Example procedure call: ! rEnter "Station 1", doSta1EntRequest, diSta1ClearEnter1, doSta1InFixture, tGripper\WObj:=wobjStation1\swMoveJoint\pPreviouspoint:=p10; ! ! Older S4C, S4C+ robots require developer functions option, I think, to use functions ! like ArgName(). I think in newer IRC5 such things are now standard. PROC rEnter( string area, VAR signaldo request, VAR signaldi signal, VAR signaldo notclear, PERS tooldata tool, \PERS wobjdata WObj \switch swMoveAbs |switch swMoveLin |switch swMoveJoint \robtarget pPreviouspoint |jointtarget jposPrevious) VAR num nDummy; VAR bool bTimeFlag; VAR errnum erBreakFlag; CONST string stFixClear:="Clear signal has been received, "; IF (NOT Present(pPreviouspoint)) AND (NOT Present(jposPrevious)) THEN TPErase; TPWrite "Neither a robtarget nor a jointtarget were provided!!!"; TPWrite "Please remedy this from where this"; TPWrite "procedure was called."; TPWrite "Backwards execution will NOT be possible!!!"; ENDIF IF (Present(jposPrevious)) AND (NOT Present(swMoveAbs)) THEN TPErase; TPWrite "The optional switch for MoveAbsJ was not provided"; TPWrite " but a jointtarget was!!!"; TPWrite "Please remedy this from where this"; TPWrite "procedure was called."; TPWrite "Backwards execution will NOT be possible!!!"; ENDIF Set request; WaitUntil signal=1\MaxTime:=2\TimeFlag:=bTimeFlag; IF bTimeFlag AND OpMode()=OP_MAN_PROG THEN TPWrite "Waiting for Clear signal, "; TPReadFK nDummy,ArgName(signal),"","",""," ",""\DIBreak:=signal\BreakFlag:=erBreakFlag; ELSE TPWrite "Waiting for Clear signal, "; TPWrite ArgName(signal); WaitDI signal,1; ENDIF TPWrite stFixClear; TPWrite ArgName(signal); Reset notclear; Reset request; BACKWARD IF (NOT Present(pPreviouspoint)) AND (NOT Present(jposPrevious)) THEN TPErase; TPWrite "Neither a robtarget nor a jointtarget were provided!!!"; TPWrite "Please remedy this from where this procedure"; TPWrite "was called."; ENDIF IF Present(swMoveAbs) THEN MoveAbsJ jposPrevious,v500,fine,Tool\WObj?WObj; ELSEIF Present(swMoveLin) THEN MoveL pPreviouspoint,v500,fine,Tool\WObj?WObj; ELSE MoveJ pPreviouspoint,v500,fine,Tool\WObj?WObj; ENDIF TPWrite "Robot clearing " + area; Set notclear; RETURN; ENDPROC PROC rExit( string area, VAR signaldo request, VAR signaldi signal, VAR signaldo notclear, PERS tooldata tool, \PERS wobjdata WObj \switch swMoveAbs |switch swMoveLin |switch swMoveJoint \robtarget pPreviouspoint |jointtarget jposPrevious) VAR num nDummy; VAR bool bTimeFlag; VAR errnum erBreakFlag; CONST string stExiting:="Robot exiting "; CONST string stReturning:="Robot Returning "; IF (NOT Present(pPreviouspoint)) AND (NOT Present(jposPrevious)) THEN TPErase; TPWrite "Neither a robtarget nor a jointtarget were provided!!!"; TPWrite "Please remedy this from where this"; TPWrite "procedure was called."; TPWrite "Backwards execution will NOT be possible!!!"; ENDIF IF (Present(jposPrevious)) AND (NOT Present(swMoveAbs)) THEN TPErase; TPWrite "The optional switch for MoveAbsJ was not provided"; TPWrite " but a jointtarget was!!!"; TPWrite "Please remedy this from where this"; TPWrite "procedure was called."; TPWrite "Backwards execution will NOT be possible!!!"; ENDIF Set request; WaitUntil signal=1\MaxTime:=2\TimeFlag:=bTimeFlag; IF bTimeFlag AND OpMode()=OP_MAN_PROG THEN TPWrite "Waiting for Clear signal, "; TPReadFK nDummy,ArgName(signal),"","",""," ",""\DIBreak:=signal\BreakFlag:=erBreakFlag; ELSE TPWrite "Waiting for Clear signal, "; TPWrite ArgName(signal); WaitDI signal,1; ENDIF TPWrite stExiting+area; ! The VAR signaldo notclear is not set here ! because some motion is necessary to get the ! robot actually clear. If it were set here ! then the robot is not clear because no Motion ! has occurred yet. Reset request; BACKWARD Reset notclear; IF Present(swMoveAbs) THEN MoveAbsJ jposPrevious,v500,fine,Tool\WObj?WObj; ELSEIF Present(swMoveLin) THEN MoveL pPreviouspoint,v500,fine,Tool\WObj?WObj; ELSE MoveJ pPreviouspoint,v500,fine,Tool\WObj?WObj; ENDIF TPWrite stReturning+area; RETURN; ENDPROC ENDMODULE
Lee Justice0 -
Thanks for your input, but I still haven't come closer to a solution. The idea from my side was to be able to replace existing WaitUntil instructions with "MyOwn_WaitUntil", a procedure where I can input the exact same parameters as with a regular WaitUntil, but also be able to add my own code aswell. In my case this would be for example to tell a PLC what the robot is waiting for using a group output.This is all fine, except for the input parameter "Condition" that is not being updated with the actual value.
In the example below I have not found a way to always get the updated value of (bFixturesReady=TRUE AND diSignal1=1) inside the proc. INOUT and VAR would work if I always just used a bool and nothing else. The same for signaldi, I could get this to work aswell. But the idea was to make a general procedure to manage all sorts of conditions.Anyone have any more ideas?MyOwn_WaitUntil bFixtureReady=TRUE AND diSignal1=1\MaxTime:=5\Visualize\Message:=""Waiting for Signal"0 -
That was why I had originally suggested making it a function.Lee Justice0
-
This is not what you asked, but this is how I have solved it previously.
PROC MyProc() !Do pre-job WaitUntil AwaitCondition(diSensor1=1); WaitUntil AwaitCondition(boolMotorRunning=TRUE); !Do post-job ENDPROC FUNC bool AwaitCondition(bool Cond) !Condition is true, return true and continue program. IF Cond = TRUE RETURN TRUE; !Condition is false, execute logic while waiting ! ! - DO OTHER STUFF - ! ! RETURN FALSE; ENDFUNC
You can then handle:\<span>num MaxTime\INOUT bool TimeFlag</span>
in the regular WaitUntil instruction.
As long as the condition is false your "DO OTHER STUFF" will execute.
When condition is true program will continue.
You can use any condition with this function.
Systemintegrator - Web / C# / Rapid / Robotstudio
If I helped, please press Vote Up
☑️2024 - RobotStudio® User Group1
Categories
- All Categories
- 5.5K RobotStudio
- 396 UpFeed
- 18 Tutorials
- 13 RobotApps
- 297 PowerPacs
- 405 RobotStudio S4
- 1.8K Developer Tools
- 250 ScreenMaker
- 2.8K Robot Controller
- 316 IRC5
- 61 OmniCore
- 7 RCS (Realistic Controller Simulation)
- 800 RAPID Programming
- AppStudio
- 3 RobotStudio AR Viewer
- 18 Wizard Easy Programming
- 105 Collaborative Robots
- 5 Job listings