Jumping at a specific line, from a routine to another one

milo_gerardi
milo_gerardi France
edited September 5 in RAPID Programming
Hi, i'm having troubles finding a proper way to go to a certain point on my program after an event comes up.
The idea is the following :
In my main routine i'm calling some sub-routines that are made for the robot to execute  different trajectories in different cases. The hole thing is looping inside a While loop. The thing is that when a specific digital output is set high, I need to jump at the end of my While loop regardless to where the pointer is in the program (main routine or sub-routine)

My first guess was to use an interruption that could bring the pointer back the main routine using a GOTO instruction for exemple. But that didn't work.
I then tried to use a custom error that is triggerd in an interruption routine. The error is raised up to the main routine using the RAISE statement. But now i can only use RETURN that will bring back the pointer at the begining of the sub-routine it was in. Whereas i would like the pointer to go at a specific line in my main routine.
Tanks for your help !
Best regards
Tagged:

Comments

  • graemepaulin
    graemepaulin New Zealand mod
    I think you need to use error recovery with a long jump:-
    Error recovery with long jump may be used to bypass the normal routine call and return mechanism to handle abnormal or exceptional conditions. To accomplish this, a specific error recovery point must be specified. By using the RAISE instruction the long jump will be performed and the execution control is passed to that error recovery point.
    Error recovery with long jump is typically used to pass execution control from a deeply nested code position, regardless of execution level, as quickly and simple as possible to a higher level.

    This is covered in the Technical Reference Manual - RAPID Kernel
  • I have read the manual but can't figure out how to use it in my case.
    Here is a (highly) siplified structure of my code :

    MODULE MainModule
        PROC Main()
            WHILE TRUE DO
                FOR i FROM x TO y DO
                    routine1;
                    routine2;
                    routine2;
                    routine1;
                ENFOR
                instruct1
                instruct2
                routine3;
            ENDWHILE
            ERROR
                ???
        ENDPROC

        TRAP ForcedEnd
            RAISE ERR_FORCED_END;
            ERROR
            IF ERRNO = ERR_FORCED_END
                RAISE;
            ENDIF
        ENDTRAP
    ENDMODULE

    The thing is that whenever the trap routine is called, i need a way to jump directly to the instruct1, that is outside the FOR loop but still inside the WHILE loop.
    About long jump, I read about specific entry point but the ERROR statement can only be placed at the end of the procedure. Is there something I've missed ?

    Thanks.
  • Forge_Engineering
    Forge_Engineering Mackay, QLD, Australia
    edited September 6
    Hi Milo, 

    With long jump, you need to include the specific error you are trying to catch in the routine you want to catch it in next to the ERROR keyword in brackets:
    PROC Main()
        !Do stuff	
    ERROR(ERR_FORCED_END)
        ! Handle error
    ENDPROC
    
    
    TRAP
        RAISE ERR_FORCED_END;
    ERROR
        RAISE;
    ENDTRAP
    

    RAPID can't jump straight from an error handler or trap routine to a specific line with a GOTO statement so you have to design your program around it. If it was me trying to do it in the least amount of lines possible I would put all my code in a subroutine from Main, catch the error in main then set a flag PERS to jump to the instruction I want and execute RETRY to re-enter the routine, then check for the flag and jump accordingly if needed:

    PERS bool b_GoToInstruct1 = FALSE;
    
    PROC Main()
        ! use custom function to execute all main code
        SubMain;
    	
    ERROR(ERR_FORCED_END)
        IF ERRNO = ERR_FORCED_END THEN
            ! Set flag for jump
            b_GoToInstruct1 = TRUE;
            ! Retry SubMain Proc
            RETRY;
        ENDIF
        ! Handle error
    ENDPROC
    
    PROC SubMain()
        WHILE TRUE DO
    
            IF b_GoToInstruct1 THEN
                ! Unset the flag
                b_GoToInstruct1 = FALSE;
                ! Goto instruct 1
                GOTO lbl_Instruct1;
            ENDIF
    <br>&nbsp;&nbsp; &nbsp;    FOR i FROM x TO y DO<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;routine1;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;routine2;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;routine2;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;routine1;<br><div>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ENFOR
            
            lbl_Instruct1:       
     </div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instruct1</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instruct2<br></div>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;routine3;<br>    ENDWHILE
    ENDPROC
    
    TRAP 
        RAISE ERR_FORCED_END;
    ERROR
        RAISE;
    ENDTRAP

    Good Luck, 

    Harry
  • It works perfectly.
    Thanks a lot !