# Random value needed

Is there a way to get a random value in RAPID?

I need it to introduce some "noise" in the control of a motor...

Something like a float ranging from 0 to 1 with a flat distribution.

Regards

• Hello,
No, there is no function to generate a random number in RAPID, so you have to implement it yourself. Here is a suggestion, which seems to work reasonably well:

LOCAL VAR num nSeed:=320;
LOCAL VAR num nSeed_age:=150;
LOCAL FUNC num Random(

VAR num nSeed,
VAR num nSeed_age)
CONST num nModulus:=655;
CONST num nMultiplier:=251;
CONST num nIncrement:=13849;
IF nSeed_age>140 THEN

nSeed:=GetTime(Sec)*GetTime(Min);
nSeed_age:=0;
ENDIF
nSeed_age:=nSeed_age+1;
nSeed:=((nMultiplier*Abs(nSeed))+nIncrement) MOD nModulus;
RETURN (nSeed/nModulus);
ENDFUNC

BR,

frpa
• Thanks for the suggestion, I will use that as a base and add some additional noise based upon the current robot position.

Btw. I just skimmed the program. It looks like the nSeed can become 0 (when sec or min =0) and this will result in extended periods of returning nIncrement MOD nModulus.

• You are right! The seeding needs to be redone so that the seed cannot be 0. Thanks for pointing that out!

• Here is a random generator, extend as needed.

It uses 2. "random" seedings ( robot position, time) and a counter + Cosinus to generate a nice random number...

Please note that I haven't bothered to check for the "flatness" of the random distribtution - so this is most likely not TRUE random.

MODULE RandomTesting

VAR num callCount;

FUNC NUM RANDOM()
VAR num val:=1;

var pos pos_current;
pos_current := CPos(Tool:=tool0 WObj:=wobj0);

!1 seeding, Seed by position
val:=val*(Abs(ROUND(pos_current.x*100,Dec:=0)) +1); !+1 to avoid mul by 0 scenario
val := 789 + val MOD 1000; !777 is just a bogus valu, since the mod might give 0

!Feel free to seed with y,z, more

!2. seeding, Seed by time
val :=val * ( GetTime(Sec)+1);
val :=val * ( GetTime(Min)+1);

!3 seeding, increment callcount and handle large nuber
callCount := callCount +1;
IF callCount > 1000 THEN
callCount := 234;
ENDIF

!finally a division to get something interesting large float number
val := val / callCount;

!get a value between 0 and 1 using COS ( math)
RETURN (0.5 + COS(val)/2);

ENDFUNC

!Testprocedure, dump a couple of numbers to the logfile
PROC TESTRANDOM()
var num arandom;

var string txt:="";

var num count:=0;

WHILE count < 18 DO
arandom := RANDOM();
txt:=txt + ValToStr(Round(arandom,Dec:=1)) + ";"; !Excel importable
count := count+1;

ENDWHILE
ErrWrite I,"random values",txt;
ENDPROC
ENDMODULE

• frpa!

I tried your RandomGen, and it works sucesfully!

But i have one question for you, how/can i decide the highest number i can get, ex no number higher then 200?

BR
• the simplest is to call random and save it in a num variable, and then multiply by your max number.
Simple pseudocode:

var num MAXNUMBER:= 200;
var num rand = RANDOM();
var num newrandom := rand * MAXNUMBER; !This gives you from 0 to 200 random

• Updated RAPID code & tested it

MODULE RandomNumber

VAR num callCount;

!Get a random number between 0 and 1
FUNC NUM RANDOM()
VAR num val:=1;

var pos pos_current;
pos_current := CPos(\Tool:=tool0 \WObj:=wobj0);

!1 seeding, Seed by position
val:=val*(Abs(ROUND(pos_current.x*100, \Dec:=0)) +1); !+1 to avoid mul by 0 scenario
val := 789 + val MOD 1000; !777 is just a bogus valu, since the mod might give 0

!Feel free to seed with y,z, more

!2. seeding, Seed by time
val :=val * ( GetTime(\Sec)+1);
val :=val * ( GetTime(\Min)+1);

!3 seeding, increment callcount and handle large number
callCount := callCount +1;
IF callCount > 1000 THEN
callCount := 234;
ENDIF

!finally a division to get something interesting large float number
val := val / callCount;

!get a value between 0 and 1 using COS ( math)
RETURN (0.5 + COS(val)/2);

ENDFUNC

!Testprocedure, dump a couple of numbers to the logfile
PROC TESTRANDOM()
var num arandom;

var string txt:="";

var num count:=0;

WHILE count < 10 DO
arandom := RANDOM();
txt:=txt + ValToStr(Round(arandom, \Dec:=4)) + ";"; !Excel importable
count := count+1;

ENDWHILE
ErrWrite \I, "random values",txt;
ENDPROC
ENDMODULE
• Nowadays you can use Rand().
-----------------
David
Swedish freelance ABB robot programmer