INTRO ----- This is a simple simulation of the Camera and ADC. It takes a .pbsim file, and outputs a set of data in cam format (which may later be converted by cam2tiff) It makes some very particular assumptions on how the camera is wired up (which bits do what) - invoke with -h for more. Look in examples/ for some demonstrations. DEMONSTRATIONS -------------- 1. To get a sample image: hawaiisim -xt -o test.cam # generate image in test mode cam2tiff test.cam test.tiff # convert datafile to tiff file. display test.tiff # show the tiff on screen. 2. To simulate a real device. pb_parse -i frame-reset-read.pbsrc -xg #parse the pbsrc instructions and simulate the output of the parser. hawaiisim -i frame-reset-read.pbsim -xo test.cam -a hum -e debug #playback the clock file and simulate the Hawaii/ADC output cam2tiff test.cam test.tiff && display test.tiff #convert the output to an image and show on screen. [Note: a copy of the .pbsim file is stored gzipped here, it compresses 11MB to 40kB. This is useful for running hawaiisim without having pb_parse on hand.] When running this normally, it prints the read and reset pixels/lines. For faster simulation, redirect stdout/stderr to /dev/null. See also: "hawaii_characterise -g" FUTURE ENHANCEMENTS ------------------- * It would be nice to support using a TIFF to specify the reset levels. Useful as a way to map bad or noisy pixels. Also useful as a way to simulate correlated-double-sampling without intervening resets. * Improve the adc interface: allow a single trigger to cause multiple reads (n reads, frequency f). * The main cause of slowdown is the use of rand(). This function isn't 'slow' per se, but it is called LOTS of times. For every instruction (i.e every line of the pbsim file), the illuminate_array() function is called. This iterates over a million pixels, and generates statistical noise (thermal and shot noise), resulting in ~ 20 calls to rand(). Workaround: use 'linear_tiff:file' rather than 'tiff:file'. Possible alternative to rand() is to read bytes directly from /dev/urandom, though this actually seems slower! * Consider adding a (quantifiable) amount of 50Hz (and harmonics) mains hum - to see whether the subsequent algorithms can correct it (or to verify that our clocking is mains-synchronous). [UK mains is typically within 0.2Hz of 50Hz, usually better: http://www.nationalgrid.com/uk/Electricity/Data/Realtime/Frequency/Freq60.htm ] => Done... what does this actually get us? * Optimisation: In the simulated (as opposed to gen_cam() ) case, with full-frame reads, we have to do 256k reads, each of which illuminates 1M pixels! So, do Lazy Evaluation: - calculate the pixel values only when we NEED them, rather than calling illuminate_array() every time. Instead, keep last value and last timestamp; then update the values before each read(), and when READ changes state. Also, when reading only a few pixels, we can forget about updating the ones we don't care about.. => Done: it now runs in 1 second, rather than many hours! * For convenience, consider accepting a zipped/bzipped .pbsim file. These can be very long, and are highly redundant. INFO ---- See here: http://en.wikipedia.org/wiki/Johnson–Nyquist_noise#Thermal_noise_on_capacitors regarding our noise model - notably noise on the resistor (ADC) and the capacitor (at reset). Compilation: "-03 -march=native -ffast-math" seem to help. Runtime can be reduced significantly (~30%). Note -ffast-math is slightly 'dodgy' for floating point, but probably OK in this context. TODO ---- ADC Edge: Currently, have arbitrarily decided that the ADC should be falling edge triggered. This ought to be a #define. (it effects the adc sampling, tests for setup/hold, and the docs) [The reason for choice is that falling edges are slightly sharper on the hardware] ADC multiple samples: At the moment, the PB is used to trigger each and every ADC. But the real-world ADC can do bursts. Use this? ADC sign and offset: Worth #defining a scale factor and offset for the ADC. Real-world ADC might have the [-2.5, +2.5] V range on ADC, where actual signal goes [0.5 , 2] V. Also, it allows us to model the hawaii better: reset *charges* the capacitors, and exposure slowly discharges them. Filetypes: Consider designing (and documenting) a file format for this output. Ideally, .cam is only for single, full-frame images. What is the general case? .dat?