Random Number Generator Example
Last Modified: 2006-11-02
find:

basket

Acroname Robotics PDF webpage version Random Number Generator Example PDF

Related
Products

Product image for BrainStem Moto 1.0 Module
BrainStem Moto 1.0 Module
Product image for Brainstem GP 1.0 Module
Brainstem GP 1.0 Module

Contents

Introduction

Simulating randomness can be a useful feature in a robot design.  If a robot can change its behavior at random, it may be able get out of situations where it would otherwise sit in an infinite loop.  Randomness may also be useful for making a robot seem less "robotic".  It could blink eyes or wiggle appendages in an appealing way. 

This example program will print a very long sequence of pseudo-random numbers.  It could be adapted to an application that requires some illusion of randomness. 

Theory

Random number generators are not random.  They just produce a very long sequence of numbers.  A typical pseudo-random number generator in a computer application does a lot of number crunching with variables many bytes long.  These methods aren't very practical on BrainStem modules.  BrainStems are very slow compared to most computers and the largest variables they can manipulate are two bytes long. 

The technique in this example uses very simple arithmetic at the expense of some program memory.  It looks up random bytes stored in tables and exclusive-ORs them together to generate new random numbers.  The result is a uniform distribution of values in the range -128 to 127. 

Source Code - EEPROM Lookup Table

With proper selection of the tables, it is possible to generate some very long sequences.  This example uses 5 tables.  The initial table indexes are the "seed" value for the generator.  For this example, they're all initialized to 0.  After generating a random number, the index into each table is incremented.  Each index wraps-around after reaching the end of the table.  The size of each table is a prime number.  This maximizes the sequence length.  With five tables and a total of 243 bytes of stored data, this program will generate 259106347 values (41*43*47*53*59) before repeating itself.  This may be overkill for a typical BrainStem application.  The basic method can be scaled down (or up) depending on the user's needs. 

So how random is it? There are lots of tests for "randomness".  However, none were tried on this method.  If analyzing random number generators is your hobby, give it a whack and let us know your results!

Note

Since this example uses EEPROM lookup in a TEA program, it will not work on GP modules before Build 9. 

Before running the program, you'll need to store the lookup table by executing the "table.bag" batch file with the Console's batch command.  You'll only need to do this once.  This batch file stores the data in TEA file slot 10 which starts at the 15th 1K chunk of memory, or address 0x3C00, in a Stem's EEPROM.  Once you've saved the lookup table, then try the program and watch all the numbers scroll by. 

/* filename: table.bag */ /* Generated with a C program */ /* using the rand() function */ /* Source table seed = 7987 */ /* Source table size = 243 */ 2 16 0x3C 0x00 1 243 234 19 2 16 0x3C 0x04 139 171 90 86 2 16 0x3C 0x08 254 243 185 181 2 16 0x3C 0x0C 59 74 14 15 2 16 0x3C 0x10 147 212 77 144 2 16 0x3C 0x14 240 28 100 206 2 16 0x3C 0x18 197 139 5 166 2 16 0x3C 0x1C 183 167 50 213 2 16 0x3C 0x20 8 13 138 85 2 16 0x3C 0x24 200 45 85 125 2 16 0x3C 0x28 186 199 81 216 2 16 0x3C 0x2C 7 41 58 193 2 16 0x3C 0x30 165 37 27 195 2 16 0x3C 0x34 133 212 87 178 2 16 0x3C 0x38 127 14 118 136 2 16 0x3C 0x3C 254 165 176 1 2 16 0x3C 0x40 107 100 59 246 2 16 0x3C 0x44 90 202 85 123 2 16 0x3C 0x48 119 134 17 183 2 16 0x3C 0x4C 46 178 225 134 2 16 0x3C 0x50 29 208 231 208 2 16 0x3C 0x54 59 133 251 167 2 16 0x3C 0x58 197 23 123 35 2 16 0x3C 0x5C 236 168 214 253 2 16 0x3C 0x60 64 48 215 238 2 16 0x3C 0x64 218 59 179 197 2 16 0x3C 0x68 76 104 209 75 2 16 0x3C 0x6C 74 157 91 214 2 16 0x3C 0x70 21 11 137 175 2 16 0x3C 0x74 171 229 168 37 2 16 0x3C 0x78 176 223 236 110 2 16 0x3C 0x7C 26 105 251 65 2 16 0x3C 0x80 159 168 54 51 2 16 0x3C 0x84 224 57 197 213 2 16 0x3C 0x88 82 165 105 139 2 16 0x3C 0x8C 241 162 1 43 2 16 0x3C 0x90 163 15 217 89 2 16 0x3C 0x94 108 173 182 165 2 16 0x3C 0x98 87 159 162 97 2 16 0x3C 0x9C 32 160 119 67 2 16 0x3C 0xA0 162 6 46 192 2 16 0x3C 0xA4 3 122 229 35 2 16 0x3C 0xA8 161 116 178 111 2 16 0x3C 0xAC 187 121 42 250 2 16 0x3C 0xB0 224 20 175 198 2 16 0x3C 0xB4 24 150 125 158 2 16 0x3C 0xB8 211 141 116 245 2 16 0x3C 0xBC 149 5 163 126 2 16 0x3C 0xC0 95 129 152 138 2 16 0x3C 0xC4 221 183 106 37 2 16 0x3C 0xC8 81 15 131 240 2 16 0x3C 0xCC 66 218 46 189 2 16 0x3C 0xD0 227 82 228 236 2 16 0x3C 0xD4 69 86 86 136 2 16 0x3C 0xD8 60 226 58 33 2 16 0x3C 0xDC 19 79 213 103 2 16 0x3C 0xE0 239 80 77 139 2 16 0x3C 0xE4 3 168 172 86 2 16 0x3C 0xE8 121 172 180 6 2 16 0x3C 0xEC 28 125 101 235 2 16 0x3C 0xF0 197 1 79

Source Code - TEA Usage Example

/* filename: random.tea */ #include <aCore.tea> #include <aPrint.tea> /* sizes of the 5 pre-stored random number tables */ #define PRIME1 41 #define PRIME2 43 #define PRIME3 47 #define PRIME4 53 #define PRIME5 59 /* locations of the 5 pre-stored random number tables */ /* data is stored in TEA slot 10 (15th 1K chunk) */ #define RTABLE1 0x3C00 #define RTABLE2 0x3C00+PRIME1 #define RTABLE3 0x3C00+PRIME1+PRIME2 #define RTABLE4 0x3C00+PRIME1+PRIME2+PRIME3 #define RTABLE5 0x3C00+PRIME1+PRIME2+PRIME3+PRIME4 /* bookkeeping variables */ char _randk1 = 0; char _randk2 = 0; char _randk3 = 0; char _randk4 = 0; char _randk5 = 0; char readEEPROM(int i) { char val = 0; asm { pushss 5 popsm aPortEEPROMRead popbs 1 } return val; } char ranval() { char val = 0; /* cobble up a pseudo-random value */ val = readEEPROM(RTABLE1 + _randk1); val = val ^ readEEPROM(RTABLE2 + _randk2); val = val ^ readEEPROM(RTABLE3 + _randk3); val = val ^ readEEPROM(RTABLE4 + _randk4); val = val ^ readEEPROM(RTABLE5 + _randk5); /* turn the crank */ _randk1 = (_randk1 + 1) % PRIME1; _randk2 = (_randk2 + 1) % PRIME2; _randk3 = (_randk3 + 1) % PRIME3; _randk4 = (_randk4 + 1) % PRIME4; _randk5 = (_randk5 + 1) % PRIME5; return val; } void main() { int i; char c; while (1) { c = ranval(); aPrint_CharDec(c); aPrint_Char('\n'); aCore_Sleep(1000); } }

Revision History:

  • 2003-07-11: Example Created.
 
 
voice: 720-564-0373, email: sales@acroname.com, address: 4822 Sterling Dr., Boulder CO, 80301-2350, privacy
© Copyright 1994-2008 Acroname, Inc., Boulder, Colorado. All rights reserved.