SNL-WaterPower / siweed

Sandia Interactive Wave Energy Education Display (SIWEED)
4 stars 2 forks source link

Random Phase generation #20

Closed nickross4444 closed 3 years ago

nickross4444 commented 4 years ago

The phase in the arduino Jonswap library is assigned with a defined seed for random number generation(123). This produces different results on the Due and on the Mega, likely because the different chip architecture(ARM vs Atmel).

DeepFriedDerp commented 4 years ago

I did some digging last night on this issue.

The Due uses the GNU GCC compiler, while the MEGA uses the arduino's standard avr-gcc compiler.

random() is considered a non-stardard (non-ISO) C function, and for some reason the code using random() will not compile for the Due on my computer. I've tried using the C-standard rand() and srand() functions (which will both compile for the MEGA and the Due) in comparison tests, but am still getting different results between the Due and the Mega.

I believe that this has something to do with the internal workings of the rand() function. It looks like when coding in pure C++, there are a series of different psuedo-random number generator (pRNG) engines available, and then a "default" engine and numerical distribution if rand() is called with not specifics set on the engine or distribution, and those defaults are OS-specific. I feel like a similar difference in rand() specifics is going on here.

I have found some source code deep in the bowels of the arduino file system (Local Disk \ Users \ [username] \ AppData \ Local \ Arduino15 \ packages \ arduino \ tools \ arm-non-eabi-gcc \ 4.8.3-2014q1 \ arm-non-eabi \ include \ c++ \ 4.8.3 \ parallel \ random.h (once you get to 4.8.3 folder, it gets pretty interesting). Anyway, this random.h looks like it has the capability of selecting the pRNG engine (I've read that the MT19937 engine can return the same results from the same seed across different OS's).

However, I cannot find the equivalent functionality in the AVR filesystem, nor do I know enough low-level C to attempt to use the information I've given here, so without more information it looks like the avr-based rand() lacks the ability to choose a particular pRNG, and the default pRNG settings are different between the mega and the due.

There may be a way to implement a 3rd party library pRNG, but the one I tried used the watchdog timer interrupt to update the random number value every 16ms. Unfortunately, the avr watchdog library will not compile on the Due. I have coded up my own variable watchdog timer software for SAMD processors, but have not yet tried with SAM. I may play around with the library I found (pRNG-1.2.2) to see if I can get a the Due to work with it. If I figure anything out, I'll share it here.

nickross4444 commented 3 years ago

Since we are running two Due's this is not longer a concern.