Recovery Coding Snippet Example; Any Examples are Highly Appreciated!

Hello all!

Would anyone mind sharing any coding snippets/examples of any recovery programs that they wouldn’t mind sharing?

I am trying to figure out how to handle the recovery & resuming of my multi-controller / multi-robot cell.

STOPING LINE:

I want the robots to stop (at end of instruction or auto-stop??) then motors off when someone requests to enter the cell. Once they exit the cell, close the door, and hit ‘resume’ button on HMI I want the cell to resume like nothing happened. (Guessing I would need a 'system input: Motors On and Start’ and put a routine in another task using multi-task and be static or semistatic?)

RECOVERY/HOMING LINE:

I am also needing to reset the line or tell all robots to go ‘home’ especially after a collision or if maintenance on the cell is required.

I understand these are very different goals, and this is my first time programming a line with recovery and want to make sure I am doing it correctly.

I have been trying to come up with a plan on my own but keep failing on finding a resolution and feeling pretty defeated.

So far I have:

I have set up world zones and am using those to signal digital IO to know what zone I was/am in,
but was curious on what the next step is?

  1. Is there a rough pattern that I need to follow or does anyone have a to-do list on things I need to cover?

  2. Do I need to use a TRAP routines? (I have struggled with TRAP routines in the past and them not triggering).

  3. Where in the Main line code would this recovery program go: before normal program execution or would it go in another task all together?

  4. Is SafeMove required?

  5. Any other Add-ins or licenses that I might need such as collision detection etc?

I have looked through the manual and online and can’t find any example using an actual cell and struggle with seeing the bigger picture with vague examples… Would anyone have anything they wouldn’t mind sharing for a recovery process similar to this? I would love to see what good practices are! I definitely learn by example so anything you got is highly appreciated!!!

I suppose you have a pushbutton for a request to enter. Map this as an input to the controller. At appropriate points in your program, look to see if this input is on and if so, stop.

Read up on path recorder, you can play the path backwards to get to a safe place to go home.

I am busy right now, getting you an example of some other code will take some time.

1 Like

I will absolutely look into path recorder! Thank you so much for your reply!

I’m not going to lie; my robot routines are pretty long. Do you think if I just record the whole thing that it would be okay?
Or do you normally break up your paths into sections? (If that makes sense!) :slight_smile:

Hi…
1 - You can start or stop the robot immediately using external signals (push-button, switch, etc.); I use the ‘Motors On’ and ‘Start’ system inputs linked to these signals. In RAPID, I have a Trap routine that monitors the physical ‘stop’ signal; as long as it is high, I keep the robot in ‘StopMove’.
2 - I don’t think it’s a good idea to save the entire path; instead, save only the specific locations where you detect a potential collision.
3 - As for return routines, I monitor based on zones. Here is an example to help you understand.

RECORD pathRecover
        robtarget PRecover;
        bool isAtivo;
    ENDRECORD

PROC MoverRoboHome_v3_1_1()
        ! ## ATTRIBUTES #############################################################################
        VAR pathRecover matPSearchL{10};
        ! ## ATTRIBUTES #############################################################################

        
        ! Waits for the robot movements to be ZEROED, i.e., when there is no movement in any robot axis ...
        WaitRob\ZeroSpeed;

 
        ! #################### Scanning the areas in search of the robot position for a safe return - safe areas for returning to HOME
        IF DOutput(R2_RoboAreaHome)=1 THEN
            ! If it is already in HOME, moves out of the zone
            MoveJ RelTool(P_HOME,0,0,0),v1000,fine,tGripperG\WObj:=wobj0;
        ELSEIF DOutput(R2_RoboAreaSafety)=1 THEN
            ! If it is already in SAFETY, moves out of the zone
            MoveJ RelTool(P_SAFETY,0,0,0),v1000,fine,tGripperG\WObj:=wobj0;
        ELSEIF (DOutput(R2_AcessandoAreaDispAntiRuidoA)=1) OR (DOutput(R2_AcessandoAreaDispAntiRuidoB)=1) THEN
            matPSearchL{1}:=[CRobT(\Tool:=tGripperG\WObj:=wDispenserAntiRuidoG),FALSE];

            matPSearchL{2}:=[Offs(matPSearchL{1}.PRecover,0,0,200),TRUE];
            matPSearchL{3}:=[P_AC_RETIRAR_AR_DISPENSER_G,TRUE];

            ! Moves to HOME from the AR Dispenser ...
            MoveL matPSearchL{2}.PRecover,v100,z5,tGripperG\WObj:=wDispenserAntiRuidoG;
            MoveL matPSearchL{3}.PRecover,v500,z200,tGripperG\WObj:=wDispenserAntiRuidoG;
        ELSEIF DOutput(R2_AcessandoAreaDestacLinerAR)=1 THEN
            matPSearchL{1}:=[CRobT(\Tool:=tGripperG\WObj:=wDispenserAntiRuidoG),FALSE];

            matPSearchL{2}:=[Offs(matPSearchL{1}.PRecover,150,0,0),TRUE];

            ! Moves to HOME from the AR Liner Detacher ...
            MoveL matPSearchL{2}.PRecover,v100,z5,tGripperG\WObj:=wDispenserAntiRuidoG;
        ELSEIF (DOutput(R2_AcessandoAreaEstDepositoAR)=1) OR (DOutput(V_R2_AcessandoAreaEstDepositoAR2)=1) THEN
            matPSearchL{1}:=[CRobT(\Tool:=tGripperG\WObj:=wDispenserAntiRuidoG),FALSE];

            matPSearchL{2}:=[Offs(matPSearchL{1}.PRecover,0,0,300),TRUE];

            ! Moves to HOME from the AR Application Conveyor on the part ...
            MoveL matPSearchL{2}.PRecover,v100,z5,tGripperG\WObj:=wDispenserAntiRuidoG;
        ELSE
             ! Moves to HOME ??
             HOME;
        ENDIF

        RETURN ;
    ERROR
        ! #############################################################################################
        ! HANDLING OF POSSIBLE ERRORS
        ! #############################################################################################

        IF ERRNO=ERR_ALRDY_MOVING THEN
            ErrWrite\W,"ERR_ALRDY_MOVING",""
                \RL2:="Robô já está se movendo ao executar uma instrução StartMove ou StartMoveRetry.";

            TRYNEXT;
        ENDIF
    ENDPROC

I hope this helps you set up your routine.

Good job.

1 Like

I would not record the entire path, just the strategic segments.

I wrote this more than a few years ago as part of a recovery system. When you find the nearest point you can decide whether or not to move to it and then add a recovery path from there.

MODULE Utility
VAR string stRobt:=stEmpty;
VAR string stClosestPoint;
CONST num nMaxRecoverDist:=2000;
PERS tooldata tCheck;
PERS string stToolName;
TASK PERS wobjdata wobjCheck:=[FALSE,TRUE,“”,[[0,0,0],[1,0,0,0]],[[0,0,0],[1,0,0,0]]];
PERS string stWobjName:=“wobj0”;

PROC FindNearestPoint()
VAR robtarget pCurrentPosition;
VAR num n12Distance:=10000;
VAR robtarget checkrobt;
VAR datapos block;

GetSysData tCheck\\ObjectName:=stToolName;
GetSysData wobjCheck\\ObjectName:=stWobjName;
pCurrentPosition:=CRobT(\\Tool:=tCheck\\WObj:=wobjCheck);
SetDataSearch "robtarget"\\InMod:="R1_Data";
WHILE GetNextSym(stRobt,block\\Recursive) DO
  GetDataVal stRobt\\TaskName:="T_ROB1", checkrobt;
  ! Compare current robot position with stored robtarget
  ! If it is less than maximum recovery distance store the name
  ! and distance from current position.
  IF (Distance(checkrobt.trans,pCurrentPosition.trans) < nMaxRecoverDist) THEN
    ! Check to see if point is within Maximum recovery
    ! but maybe farther than last compared point.
    ! Should update n12Distance if closer point is found.
    IF Distance(checkrobt.trans,pCurrentPosition.trans) < n12Distance THEN
      n12Distance:=Distance(checkrobt.trans,pCurrentPosition.trans);
      stClosestPoint:=stRobt;
    ELSE
      ! Do nothing, point is farther from last found point
      ! within max recover distance nMaxRecoverDist.
    ENDIF
  ENDIF
ENDWHILE
IF n12Distance >= nMaxRecoverDist THEN
  TPWrite "Nearest taught point is Not Found!!!  Caution!!!";
  TPWrite "Not close enough to a known taught point!!!";
  TPWrite "Active tool used to check was " + stToolName;
  TPWrite "Active work object used to check was " + stWobjName;
ELSE
  TPWrite "Nearest taught point is: " + stClosestPoint;
  TPWrite "Distance from current position is: "\\Num:=n12Distance;
  TPWrite "Active tool used to check was " + stToolName;
  TPWrite "Active work object used to check was " + stWobjName;
ENDIF

ENDPROC

ENDMODULE

1 Like