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
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.
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
FOR i FROM x TO y DO
routine1;
routine2;
routine2;
routine1;
ENFOR
lbl_Instruct1:
instruct1
instruct2
routine3;
ENDWHILE
ENDPROC
TRAP
RAISE ERR_FORCED_END;
ERROR
RAISE;
ENDTRAP
Good Luck,
Harry
It works perfectly.
Thanks a lot !