GPS Simulation

Introduction
This page details experiences using LimeSDR to simulate GPS. Note, update (Aug 15, 2017) - The center frequency should be corrected below to 1575.42MHz. It would marginally work with the original 1545.42 but 1575.42 is rock solid gps sim performance.

These experiments were inspired by the excellent procedure written up here. We want to use a similar process to target real devices, and have had luck with a qstarz 818XT bluetooth gps device, and a Galaxy S4 after using airplane mode, restart and patience. The coverage area is at least a room, even with -42db PAD attenuation. Here I am visiting Trinity College Cambridge with the qstarz and it's app.



Setup
Software to git clone - https://github.com/osqzss/gps-sdr-sim Follow the instructions on the github page for how to compile, it is a very easy procedure on Ubuntu with build-essential package installed. $ gcc gpssim.c -lm -O3 -o gps-sdr-sim Note there is a setting in gpssim.h for USER_MOTION_SIZE default 3000 max duration at 10MHz (300 seconds). You can increase that to 6000 or more to get longer default running times. The default sample rate for gps-sdr-sim is 2.6e6, 16 bit I/Q data format. LimeSDR is known to work with 10e6, and 8 bit interleaved I/Q data format converted to complex float in the graph. That is too slow to generate in real time, depending on your cpu, so one strategy is to create an rf data file non-realtime and then transmit that with a simple gnuradio python script created in gnuradio-companion. The gps-fake-out project links to a grc file, or it's easy to create your own. That example project simultaneous transmits the rf data file and also collects rf data for later analysis with Matlab and SoftGNSS. I found it useful to replace the file sink with an fft display slightly offset, and 20e6 input rate. The last puzzle piece needed are ephemeris data to feed gps-sdr-sim (required), RINEX v2 format ( read all about it here - especially the file name format). There is a global network of International GNSS Service installations providing up to date data, which may be accessed with anonymous ftp from the Goddard Space Flight Center ftp -p cddis.gsfc.nasa.gov Login anonymous 'ftp' and email for password. Use the merged GPS broadcast ephemeris file found in /pub/gps/data/daily/2017/brdc/. The filename convention is 'brdc' + + '0.' + + 'n.Z' 'n' for gps (don't get the 'g' files, that is glonass), and 'Z' for compressed. Day of year can be found with $ date +%j Get yesterdays - for example, today, Feb 28, 2017, I would get 'brdc0580.17n.Z', uncompress $ uncompress brdc0580.17n.Z Pick a place - All you need now is a location to go, Google maps is good for entering latitude,longitude and seeing where it goes, or pick a spot, right click and pick "Directions to here" and a little url hacking to get the coordinates, like 1.8605853,73.5213033 for a spot in the Maldives. To do: use the gpssim with a user motion file instead of a static location, there is even support for Google Earth and SatGen software.

Execution
Get ready to host some large files, ranging from 5 to 20GB in size, if going with a larger USER_MOTION_SIZE full duration and/or trying 16 bit. Create the rf data file, using 10e6 samples per second in interleaved 8bit I/Q sample format, using the day of year 059 merged broadcast ephemeris file: $ ./gps-sdr-sim -e brdc0590.17n -l 1.8605853,73.5213033,5 -t 2017/02/28,22:00:00 -o gpssim_10M.s8 -s 10e6 -b 8 -v Using static location mode. 9.313e-09   0.000e+00   -5.960e-08    0.000e+00 9.011e+04   0.000e+00   -1.966e+05    0.000e+00 1.86264514923e-09  1.77635683940e-15     319488      1938 18 Start time = 2017/02/28,22:00:00 (1938:252000) Duration = 600.0 [sec] 02  78.1   5.0  25142702.4   4.5 04  305.9  10.6  24630434.2   4.0 10  244.0  20.9  23656748.6   3.2 12  174.6  31.9  22801339.9   2.6 13   59.8  27.2  23001942.1   2.8 15   80.1  60.3  20615340.0   1.7 18  273.8  42.7  21969027.9   2.1 20    3.4  36.7  22141445.5   2.3 21  322.3  14.4  24860118.2   3.7 24  152.1  21.2  23574508.7   3.2 25  227.1  49.6  21537006.8   1.9 26  310.2   0.2  25799081.3   5.1 29    2.7  52.0  21259731.6   1.8 32  211.7   0.4  25733242.7   5.0 Time into run =  1.6 then get some coffee - it's a slow single threaded process which is why we have to create a data file and then transmit it instead of realtime radio broadcast. When done make sure your gnuradio-companion graph is setup with the right source filename, data types, sink driver, antenna, etc. Anything miss-matched can cause it to frustratingly run but not work. self.blocks_file_source_0 = blocks.file_source(gr.sizeof_char*1, "/home/chuck/src/gps-sdr-sim/gpssim_10M.s8", False) self.blocks_interleaved_char_to_complex_0 = blocks.interleaved_char_to_complex(False) self.osmosdr_sink_0 = osmosdr.sink( args="numchan=" + str(1) + " " + "device=soapy,lime=0" ) self.osmosdr_sink_0.set_antenna("BAND1", 0) Then click the run button or create top_block.py and run it on the command line and your gps simulated broadcast should be visible to devices a few inches away from the antenna. You can play with various gain settings in the sink block - looks like a setting of '0' sets the power amp driver to -52 db attenuatin and a setting of 10 you get -42 db: [INFO] SoapyLMS7::setGain(Tx, 0, PAD, -42 dB)

Results
Now with emissions in progress try various devices and experience the wonders of rf, distance, position orientation, how you hold you hand, etc can all effect the SNR. It may take some trickery as many receivers have build in processes to speed up signal lock, such as obtaining their own ephemeris etc. For the smart phone Galaxy S4 I put it in airplane mode, restart, open GpsTEST app and altho it found many satellites very fast, it took a long time to actually get a fix. Just found the QStarz snr jumped considerably when a hand is placed slightly behind it. Anyway, here's the screenshots of simulating location in the Maldives created above, using the QStarz app: