Is it possible to have non optional mutually exclusive parameters in routine declaration?

I am curious if there is a syntax that makes it possible to have a routine declaration with a non optional choice between two parameters.

Logically it would look like below, but this gives syntax error.


PROC MyRoutine(num NumParameter |string StringParameter)
        !Do something
ENDPROC

Internally RAPID uses something similar in several instructions, one example being SearchL.
That makes me think it is possible, but I just don’t know the syntax.

Any help would be greatly appreciated.

Hi !
Yes, you can have “list” of parameters in your parameters declaration. In your example you are missing backslash in front of “num”.

I have small function to select frame either by boolean condition or by array index:

    FUNC wobjdata SelectFrame(\bool Condition | num Index, wobjdata Selections{*})
        IF Present(Condition) THEN
            IF NOT Condition THEN
                RETURN Selections{1}; ! "false" result
            ELSE
                RETURN Selections{2}; ! "true" result
            ENDIF
        ELSE
            RETURN Selections{Index};
        ENDIF
    ENDFUNC

Fritz.

Hi,

Thank you, but you misunderstood the question.
If I put a backslash in my example I get optional parameters, and I specifically ask for NON optional, like in SearchL, where you MUST use either a signaldi as argument OR a PERS bool, but never none of them.

I need the call to the procedure call to be either

MyRoutine “String argument”;

or

MyRoutine 23;

but NOT

MyRoutine \StringParameter:=“StringArgument”;

Hi !
No, current syntax rules do not allow it by my best knowledge.
Unfortunately design-time syntax check does not care if you miss all of them. Only way is to implement runtime check to catch that type of errors.
Maybe it would be good feature request to ABB.
Fritz.

The only thing I can think of to work around this is to require both, then use a switch parameter to ignore one or the other inside the procedure.

Thank you for the suggestion, but unfortunately it does not solve my problem.
I need to intercept every call to SearchL with my own wrapper routine. In order for that to work, my routine has to declare exactly the same parameters as the built-in SearchL.

Hi…

Good morning… I believe you misinterpreted SearchL!! What exists is a choice between possible choices of the same type, switch, but not num|String. As far as I know, what you want is not possible. SearchL uses something like: SearchL [\Stop] | [\PStop] | [\SStop] | [\Sup] …) and to do this you should do: SearchL (\switch Stop | switch PStop | switch SStop | switch Sup …)
I hope this helps.

Good Job

Hi

No, I have not misinterpreted SearchL. In SearchL you have to use either signaldi or persistent bool.
In my example in the question I wanted to do the same but with string and num.

Look at this text from the manual (see the bold part).

SearchL [\Stop] | [\SStop] | [\Sup] Signal | PersBool [\Flanks] | [\PosFlank] | [\NegFlank] | [\HighLevel] | [\LowLevel] SearchPoint ToPoint [\ID] Speed [\V] | [\T] Tool [\WObj] [\Corr] [\TLoad]

So, I know it is possible, I just dont know if it is possible at the user level.

Best regards

Hi !

Without knowing what you need to do inside routine is difficult to give suggestions. But one option would be to use string in both cases. You can always convert string back to numeric value.

Fritz.

What I was thinking with my suggestion goes like this:

PROC MyRoutine(string stMyString,num nMyNum\switch swString|switch swNum)
   IF (NOT Present(swString)) AND (NOT Present(swNum)) THEN
     !Make the user correct the procedure call to choose one
   ENDIF
   IF Present(swString) THEN
      !Use the String parameter
   ELSEIF Present(swNum) THEN
      !Use the num parameter
   ENDIF

Both string and num are required for the procedure call, but the mutually exclusive switch parameters decide which one to use.

Here comes implementation of my suggestion:

PROC MyRoutine(string MyParameter)
VAR dnum dnumParameter;
VAR bool parameterIsNumeric;

parameterIsNumeric := StrToVal(MyParameter, dnumParameter);
IF parameterIsNumeric THEN
! use dnum
ELSE
! use string
ENDIF
ENDPROC

MyRoutine “Hello World!”;
MyRoutine ValToStr(123.456789);

Fritz.

Thank you all for your suggestions — I really appreciate the time and effort you’ve put into helping.

Unfortunately, I can’t make use of the proposed solutions, and I’d like to give a bit more context as to why.

I’ve built an add-in that provides additional functionality for handling home positions and safer movements. For this add-in to work correctly, I need to create wrapper routines for all built-in movement instructions.
That means that when a programmer uses, for example, a MoveJ instruction, it’s not the built-in function being executed — it’s my wrapper routine.

However, with SearchL I’m unable to exactly match the signature of the built-in instruction. This is the reason I asked the question here. I already have a workaround: I can almost mimic the signature, but I have to remove the option to call SearchL with a pers bool. Instead, if that functionality is needed, the programmer has to call SearchLBool — a separate routine I created that behaves the same as SearchL, just restricted to using a pers bool.

Again, I truly appreciate all the suggestions. At this point, I mainly need to know whether what I’m trying to do is actually possible or not. Since the built-in instruction supports this, I’m hoping there is some way to replicate that behavior.

Hi…
I apologize, as I was the one who didn’t understand. You are correct, and what you want is not supported by RS, unfortunately.
One solution to avoid having too many procedures is to use a single parameter.
In this example, only one optional parameter is valid.

    PROC tt(\tooldata tool2P|wobjdata wobj2P|string str)
        ! CODE ...
    ENDPROC

    PROC Test()
        tt\tool2P:=tGripperG\wobj2P:=wobj0; ! NOK
        tt\str:="teste";                    ! Ok
    ENDPROC

Perhaps this will help.

Good job!