Random value needed
Laro88
✭
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
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
0
Comments
-
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,
frpa0 -
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.
0 -
You are right! The seeding needs to be redone so that the seed cannot be 0. Thanks for pointing that out!
0 -
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
0 -
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?BR0 -
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
0 -
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
0 -
Nowadays you can use Rand().-----------------
David
Swedish freelance ABB robot programmer0 -
Newman said:Nowadays you can use Rand().0
-
Categories
- All Categories
- 5.5K RobotStudio
- 396 UpFeed
- 18 Tutorials
- 13 RobotApps
- 297 PowerPacs
- 405 RobotStudio S4
- 1.8K Developer Tools
- 250 ScreenMaker
- 2.8K Robot Controller
- 316 IRC5
- 61 OmniCore
- 7 RCS (Realistic Controller Simulation)
- 800 RAPID Programming
- AppStudio
- 3 RobotStudio AR Viewer
- 18 Wizard Easy Programming
- 105 Collaborative Robots
- 5 Job listings