I have to create a random function that generates a number between 1 and 100 and if the number is greater than 50, do one cycle, if less than another.
How can i do using rapid code?
You could start by posting this question in the forum category for Rapid programming. This one is for robotstudio feedback. ![]()
Or you can try this:
FUNC num fRandomGenerator()
VAR num nRandom;
VAR num nMinute;
VAR num nSecond;
VAR num nArrayPointer1;
VAR num nArrayPointer2;
! you could also put numbers out of order within the array elements, allow duplicates if you like
VAR num myNumArray10x10{10,10}:=[[1,2,3,4,5,6,7,8,9,10],[91,92,93,94,95,96,97,98,99,100],[21,22,23,24,25,26,27,28,29,30],[61,62,63,64,65,66,67,68,69,70]
,[51,52,53,54,55,56,57,58,59,60],[41,42,43,44,45,46,47,48,49,50],[31,32,33,34,35,36,37,38,39,40],[71,72,73,74,75,76,77,78,79,80]
,[81,82,83,84,85,86,87,88,89,90],[11,12,13,14,15,16,17,18,19,20]];
! Random number generation based on minutes and seconds of system time
nMinute:=GetTime(\Min);
nSecond:=GetTime(\Sec);
IF nMinute = 0 THEN
! Cannot point to array index 0, will cause array index out of bounds
nArrayPointer1 := 1;
ELSEIF nMinute >= 1 AND nMinute <= 6 THEN
nArrayPointer1 := 1;
ELSEIF nMinute >= 7 AND nMinute <= 12 THEN
nArrayPointer1 := 2;
ELSEIF nMinute >= 13 AND nMinute <= 18 THEN
nArrayPointer1 := 3;
ELSEIF nMinute >= 19 AND nMinute <= 24 THEN
nArrayPointer1 := 4;
ELSEIF nMinute >= 25 AND nMinute <= 30 THEN
nArrayPointer1 := 5;
ELSEIF nMinute >= 31 AND nMinute <= 36 THEN
nArrayPointer1 := 6;
ELSEIF nMinute >= 37 AND nMinute <= 42 THEN
nArrayPointer1 := 7;
ELSEIF nMinute >= 43 AND nMinute <= 48 THEN
nArrayPointer1 := 8;
ELSEIF nMinute >= 49 AND nMinute <= 54 THEN
nArrayPointer1 := 9;
ELSEIF nMinute >= 55 AND nMinute <= 60 THEN
nArrayPointer1 := 10;
ENDIF
IF nSecond = 0 THEN
! Cannot point to array index 0, will cause array index out of bounds
nArrayPointer2 := 1;
ELSEIF nSecond >= 1 AND nSecond <= 6 THEN
nArrayPointer2 := 1;
ELSEIF nSecond >= 7 AND nSecond <= 12 THEN
nArrayPointer2 := 2;
ELSEIF nSecond >= 13 AND nSecond <= 18 THEN
nArrayPointer2 := 3;
ELSEIF nSecond >= 19 AND nSecond <= 24 THEN
nArrayPointer2 := 4;
ELSEIF nSecond >= 25 AND nSecond <= 30 THEN
nArrayPointer2 := 5;
ELSEIF nSecond >= 31 AND nSecond <= 36 THEN
nArrayPointer2 := 6;
ELSEIF nSecond >= 37 AND nSecond <= 42 THEN
nArrayPointer2 := 7;
ELSEIF nSecond >= 43 AND nSecond <= 48 THEN
nArrayPointer2 := 8;
ELSEIF nSecond >= 49 AND nSecond <= 54 THEN
nArrayPointer2 := 9;
ELSEIF nSecond >= 55 AND nSecond <= 60 THEN
nArrayPointer2 := 10;
ENDIF
nRandom:=myNumArray10x10{nArrayPointer1,nArrayPointer2};
RETURN nRandom;
ENDFUNC
I just put it together, it is yet untested, should work.
I have been testing, it works. I like it better with the array jumbled up, like this:
VAR num myNumArray10x10{10,10}:=[[51,22,3,14,5,86,77,8,29,70],[91,42,93,74,95,16,97,38,99,90],[21,2,23,24,35,26,37,28,9,30],[61,72,83,84,65,76,67,18,79,50]
,[1,12,33,54,75,36,57,88,59,40],[41,92,43,34,45,46,17,78,49,80],[31,82,53,44,25,56,27,98,19,20],[71,62,13,94,55,66,7,48,69,10]
,[81,32,63,4,85,6,87,58,89,100],[11,52,73,64,15,96,47,68,39,60]];
Hello,
Here, what I use:
!To get Ramdom more random
LOCAL VAR num callCount;
!Get a random number between 0 and 1
LOCAL 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
I made a revision so that the numbers used are tracked, therefore using only once, until all have been used. Then it will be reset.
MODULE RANDOM_GEN
! REV 1, added bool array to track numbers already used, no duplicates.
! Added counter for total of numbers used
! Boolean array to keep track of which numbers have been used
PERS bool bUsedArray{10,10}:=[[TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE],[TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE]
,[TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE],[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE],[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE]
,[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE],[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE],[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE]
,[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE],[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE]];
! Counter for how many total numbers, number range. In this case, 1-100
PERS num nNumbersUsed;
FUNC num fRandomGenerator()
VAR num nRandom;
VAR num nMinute;
VAR num nSecond;
VAR num nArrayPointer1;
VAR num nArrayPointer2;
CONST num myNumArray10x10{10,10}:=[[51,22,83,14,5,86,77,8,29,70],[91,42,93,74,45,16,87,38,99,90],[21,2,23,24,35,26,37,28,89,30],[61,72,3,84,65,76,67,18,79,50]
,[1,12,33,54,75,36,57,88,59,40],[41,92,43,34,95,46,17,78,49,80],[31,82,53,44,25,56,27,98,19,20],[71,62,13,94,55,66,7,48,69,10]
,[81,32,63,4,85,6,97,58,9,100],[11,52,73,64,15,96,47,68,39,60]];
! Random number generation based on minutes and seconds of system time
nMinute:=GetTime(\Min);
nSecond:=GetTime(\Sec);
IF nMinute = 0 THEN
! Cannot point to array index 0, will cause array index out of bounds
nArrayPointer1 := 1;
ELSEIF nMinute >= 1 AND nMinute <= 6 THEN
nArrayPointer1 := 1;
ELSEIF nMinute >= 7 AND nMinute <= 12 THEN
nArrayPointer1 := 2;
ELSEIF nMinute >= 13 AND nMinute <= 18 THEN
nArrayPointer1 := 3;
ELSEIF nMinute >= 19 AND nMinute <= 24 THEN
nArrayPointer1 := 4;
ELSEIF nMinute >= 25 AND nMinute <= 30 THEN
nArrayPointer1 := 5;
ELSEIF nMinute >= 31 AND nMinute <= 36 THEN
nArrayPointer1 := 6;
ELSEIF nMinute >= 37 AND nMinute <= 42 THEN
nArrayPointer1 := 7;
ELSEIF nMinute >= 43 AND nMinute <= 48 THEN
nArrayPointer1 := 8;
ELSEIF nMinute >= 49 AND nMinute <= 54 THEN
nArrayPointer1 := 9;
ELSEIF nMinute >= 55 AND nMinute <= 60 THEN
nArrayPointer1 := 10;
ENDIF
IF nSecond = 0 THEN
! Cannot point to array index 0, will cause array index out of bounds
nArrayPointer2 := 1;
ELSEIF nSecond >= 1 AND nSecond <= 6 THEN
nArrayPointer2 := 1;
ELSEIF nSecond >= 7 AND nSecond <= 12 THEN
nArrayPointer2 := 2;
ELSEIF nSecond >= 13 AND nSecond <= 18 THEN
nArrayPointer2 := 3;
ELSEIF nSecond >= 19 AND nSecond <= 24 THEN
nArrayPointer2 := 4;
ELSEIF nSecond >= 25 AND nSecond <= 30 THEN
nArrayPointer2 := 5;
ELSEIF nSecond >= 31 AND nSecond <= 36 THEN
nArrayPointer2 := 6;
ELSEIF nSecond >= 37 AND nSecond <= 42 THEN
nArrayPointer2 := 7;
ELSEIF nSecond >= 43 AND nSecond <= 48 THEN
nArrayPointer2 := 8;
ELSEIF nSecond >= 49 AND nSecond <= 54 THEN
nArrayPointer2 := 9;
ELSEIF nSecond >= 55 AND nSecond <= 60 THEN
nArrayPointer2 := 10;
ENDIF
WHILE nRandom = 0 DO
IF NOT bUsedArray{nArrayPointer1,nArrayPointer2} THEN
nRandom:=myNumArray10x10{nArrayPointer1,nArrayPointer2};
bUsedArray{nArrayPointer1,nArrayPointer2}:=TRUE;
ELSE
FOR i FROM 1 TO 10 DO
FOR j FROM 1 TO 10 DO
IF bUsedArray{i,j} = FALSE THEN
bUsedArray{i,j}:= TRUE;
nRandom:=myNumArray10x10{i,j};
IF (i <= 10) AND (j <= 10) THEN
IF nRandom = 0 STOP;
Incr nNumbersUsed;
! all of the array positions have been used, this is the
! last one, time to reset all to FALSE
IF nNumbersUsed = 100 ResetBool;
RETURN nRandom;
ENDIF
ENDIF
ENDFOR
ENDFOR
ENDIF
ENDWHILE
IF nRandom = 0 STOP;
Incr nNumbersUsed;
! all of the array positions have been used, this is the
! last one, time to reset all to FALSE
IF nNumbersUsed = 100 ResetBool;
RETURN nRandom;
ENDFUNC
PROC testFunc()
VAR num nTest;
nTest:=fRandomGenerator();
TPWrite "Random number generated is: "\Num:=nTest;
WaitTime 5;
ENDPROC
PROC ResetBool()
FOR i FROM 1 TO 10 DO
FOR j FROM 1 TO 10 DO
bUsedArray{i,j}:=FALSE;
ENDFOR
ENDFOR
nNumbersUsed:=0;
ENDPROC
ENDMODULE
I noticed today that I left some of the bUsed array TRUE after I had been testing. If you would like to use this code please make sure that you make them all FALSE first. Too late for me to edit that post. :s
Nowadays you can use Rand()