Forum Migration Notice
We're transitioning to a more modern community platform by the end of this year. Learn about the upcoming changes and what to expect.

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.
<div>PROC MyRoutine(num NumParameter |string StringParameter)</div><div>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;!Do something</div><div>ENDPROC</div>

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.
//Markus Näslund
Tagged:

Comments

  • 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:

    &nbsp; &nbsp; FUNC wobjdata SelectFrame(\bool Condition | num Index, wobjdata Selections{*})<br>&nbsp; &nbsp; &nbsp; &nbsp; IF Present(Condition) THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IF NOT Condition THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RETURN Selections{1}; ! "false" result<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RETURN Selections{2}; ! "true" result<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ENDIF<br>&nbsp; &nbsp; &nbsp; &nbsp; ELSE<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RETURN Selections{Index};<br>&nbsp; &nbsp; &nbsp; &nbsp; ENDIF<br>&nbsp; &nbsp; 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"; 


    //Markus Näslund
  • 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.
    Lee Justice
  • 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.
    //Markus Näslund
  • mandolas
    mandolas
    edited November 11
    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

    //Markus Näslund
  • 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.
    Lee Justice
  • Fritz
    Fritz
    edited November 14
    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.
    Post edited by Fritz on
  • 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.

    //Markus Näslund
  • mandolas
    mandolas
    edited 1:24PM
    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!