mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 07:13:03 +00:00 
			
		
		
		
	- Major changes:
- The executable file and the default configuration file is now changed from "./install/mercurio" and "./conf/mercurio.conf" to "./install/gnss-sdr" and "./conf/gnss-sdr.conf", respectively.
        - Configuration file structure changed to define in a single entry the internal sampling frequency (after the signal conditioner). NOTICE that this change affects the all the adapters (acquisition, tracking, telemetry_decoder, observables, and PVT). All the adapters are now modified to work with this feature.
        - Moved several in-line GPS L1 CA parameters (a.k.a magic numbers..) to ./src/core/system_parameters/GPS_L1_CA.h definition file.
        - Tracking blocks now uses DOUBLE values in their outputs.
        - Observables and PVT now are separated. PVT and their associated libraries are moved to ./src/algorithms/PVT
        - Temporarily disabled the RINEX output (I am working on that!)
        - GNSS-SDR screen output now gives extended debug information of the receiver status and events. In the future, this output will be redirected to a log file.
- Bug fixes:
        - FILE_SIGNAL_SOURCE now works correctly when the user configures GNSS-SDR to process the entire file.
        - GPS_L1_CA_DLL_PLL now computes correctly the PRN start values.
        - GPS_L1_CA_DLL_FLL_PLL now computes correctly the PRN start values.
        - Several modifications in GPS_L1_CA_Telemetry_Decoder, GPS_L1_CA_Observables, and GPS_L1_CA_PVT modules to fix the GPS position computation.
- New features
        - Tracking blocks perform a signal integrity check against NaN outliers before the correlation process.
        - Tracking and PVT binary dump options are now documented and we provide MATLAB libraries and sample files to read it. Available in ./utils/matlab" and "./utils/matlab/libs"
        - Observables output rate can be configured. This option enables the GPS L1 CA PVT computation at a maximum rate of 1ms.
        - GPS_L1_CA_PVT now can perform a moving average Latitude, Longitude, and Altitude output for each of the Observables output. It is configurable using the configuration file.
        - Added Google Earth compatible Keyhole Markup Language (KML) output writer class (./src/algorithms/PVT/libs/kml_printer.h and ./src/algorithms/PVT/libs/kml_printer.cc ). You can see the receiver position directly using Google Earth.
        - We provide a master configuration file which includes an in-line documentation with all the new (and old) options. It can be found in ./conf/master.conf
git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@84 64b25241-fba3-4117-9849-534c7e92360d
			
			
This commit is contained in:
		
							
								
								
									
										2
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								README
									
									
									
									
									
								
							| @@ -66,7 +66,7 @@ In order to do profiling, you'll have to install google-perftools library. | |||||||
| 	- PERFTOOLS$ sudo make install | 	- PERFTOOLS$ sudo make install | ||||||
| 	 | 	 | ||||||
| Once google-perftools is installed, you can use the script "profiler" which is placed  | Once google-perftools is installed, you can use the script "profiler" which is placed  | ||||||
| in the root folder of MERCURIO sources. The script must be run as root since it makes use | in the root folder of GNSS-SDR sources. The script must be run as root since it makes use | ||||||
| of "nice". The result of the profiling are two files, mercurio.cpu.prof and mercurio.head.prof.0001.heap, | of "nice". The result of the profiling are two files, mercurio.cpu.prof and mercurio.head.prof.0001.heap, | ||||||
| that contain the results for CPU and HEAP profiling. You can use google-perftools' script pprof | that contain the results for CPU and HEAP profiling. You can use google-perftools' script pprof | ||||||
| to analyze the recorded data. | to analyze the recorded data. | ||||||
|   | |||||||
							
								
								
									
										222
									
								
								conf/gnss-sdr.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								conf/gnss-sdr.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,222 @@ | |||||||
|  | ; MASTER configuration file | ||||||
|  | ; This file should be updated with the latest changes in the configuration parameters, as a sample configuration file. | ||||||
|  | ; use RELATIVE file path in this configuration file | ||||||
|  | ; Sample for a configuration file for GNSS-SDR | ||||||
|  |  | ||||||
|  | [GNSS-SDR] | ||||||
|  |  | ||||||
|  | ;######### GLOBAL OPTIONS ################## | ||||||
|  | ;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. | ||||||
|  | GNSS-SDR.internal_fs_hz=4000000 | ||||||
|  |  | ||||||
|  | ;######### CONTROL_THREAD CONFIG ############ | ||||||
|  | ControlThread.wait_for_flowgraph=false | ||||||
|  |  | ||||||
|  | ;######### SIGNAL_SOURCE CONFIG ############ | ||||||
|  | ;#implementation: Use only File_Signal_Source in this version | ||||||
|  | SignalSource.implementation=File_Signal_Source | ||||||
|  |  | ||||||
|  | ;#filename: path to file with the captured GNSS signal samples to be processed | ||||||
|  | SignalSource.filename=/media/DATALOGGER/signals/Agilent GPS Generator/cap2/agilent_cap2.dat | ||||||
|  |  | ||||||
|  | ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. | ||||||
|  | SignalSource.item_type=gr_complex | ||||||
|  |  | ||||||
|  | ;#sampling_frequency: Original Signal sampling frequency in [Hz]  | ||||||
|  | SignalSource.sampling_frequency=4000000 | ||||||
|  |  | ||||||
|  | ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. | ||||||
|  | SignalSource.samples=0 | ||||||
|  |  | ||||||
|  | ;#repeat: Repeat the processing file. Disable this option in this version | ||||||
|  | SignalSource.repeat=false | ||||||
|  |  | ||||||
|  | ;#dump: Dump the Signal source data to a file. Disable this option in this version | ||||||
|  | SignalSource.dump=false | ||||||
|  |  | ||||||
|  | ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. | ||||||
|  | ; it helps to not overload the CPU, but the processing time will be longer.  | ||||||
|  | SignalSource.enable_throttle_control=false | ||||||
|  |  | ||||||
|  | ;######### SIGNAL_CONDITIONER CONFIG ############ | ||||||
|  | ;## Enables and configures a real-time resampler. Please disable it in this version. | ||||||
|  | ;implementation: Pass_Through disables this block | ||||||
|  | SignalConditioner.implementation=Pass_Through | ||||||
|  | SignalConditioner.item_type=gr_complex | ||||||
|  | SignalConditioner.sample_freq_in=4000000 | ||||||
|  | SignalConditioner.sample_freq_out=4000000 | ||||||
|  | SignalConditioner.dump=false | ||||||
|  |  | ||||||
|  | ;######### CHANNELS CONFIGURATION CONFIG ############ | ||||||
|  | ;#count: Number of avalable satellite channels. | ||||||
|  | Channels.count=6 | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION GLOBAL CONFIG ############ | ||||||
|  |  | ||||||
|  | ;#dump: Enable or disable the acquisition internal data file logging [true] or [false]  | ||||||
|  | Acquisition.dump=false | ||||||
|  |  | ||||||
|  | ;#filename: Log path and filename | ||||||
|  | Acquisition.dump_filename=./acq_dump.dat | ||||||
|  |  | ||||||
|  | ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. | ||||||
|  | Acquisition.item_type=gr_complex | ||||||
|  |  | ||||||
|  | ;#if: Signal intermediate frequency in [Hz]  | ||||||
|  | Acquisition.if=0 | ||||||
|  |  | ||||||
|  | ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] | ||||||
|  | Acquisition.sampled_ms=1 | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CHANNELS CONFIG ###### | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 0 CONFIG ############ | ||||||
|  | ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] | ||||||
|  | Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  |  | ||||||
|  | ;#threshold: Acquisition threshold | ||||||
|  | Acquisition0.threshold=70 | ||||||
|  |  | ||||||
|  | ;#doppler_max: Maximum expected Doppler shift [Hz] | ||||||
|  | Acquisition0.doppler_max=10000 | ||||||
|  |  | ||||||
|  | ;#doppler_max: Doppler step in the grid search [Hz] | ||||||
|  | Acquisition0.doppler_step=250 | ||||||
|  |  | ||||||
|  | ;#satellite: Satellite PRN ID for this channel. Disable this option to random search | ||||||
|  | ;Acquisition0.satellite=14 | ||||||
|  |  | ||||||
|  | ;#repeat_satellite: Use only jointly with the satellte PRN ID option.  | ||||||
|  | ;#Enable repeat_satellite to keep searching the same satellite during the runtime. | ||||||
|  | ;Acquisition0.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 1 CONFIG ############ | ||||||
|  | Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition1.threshold=70 | ||||||
|  | Acquisition1.doppler_max=10000 | ||||||
|  | Acquisition1.doppler_step=250 | ||||||
|  | ;Acquisition1.satellite=32 | ||||||
|  | ;Acquisition1.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 2 CONFIG ############ | ||||||
|  | Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition2.threshold=70 | ||||||
|  | Acquisition2.doppler_max=10000 | ||||||
|  | Acquisition2.doppler_step=250 | ||||||
|  | ;Acquisition2.satellite=11 | ||||||
|  | ;Acquisition2.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 3 CONFIG ############ | ||||||
|  | Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition3.threshold=70 | ||||||
|  | Acquisition3.doppler_max=10000 | ||||||
|  | Acquisition3.doppler_step=250 | ||||||
|  | ;Acquisition3.satellite=1 | ||||||
|  | ;Acquisition3.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 4 CONFIG ############ | ||||||
|  | Acquisition4.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition4.threshold=70 | ||||||
|  | Acquisition4.doppler_max=10000 | ||||||
|  | Acquisition4.doppler_step=250 | ||||||
|  | ;Acquisition4.satellite=31 | ||||||
|  | ;Acquisition4.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 5 CONFIG ############ | ||||||
|  | Acquisition5.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition5.threshold=70 | ||||||
|  | Acquisition5.doppler_max=10000 | ||||||
|  | Acquisition5.doppler_step=250 | ||||||
|  | ;Acquisition5.satellite=20 | ||||||
|  | ;Acquisition5.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 6 CONFIG ############ | ||||||
|  | Acquisition6.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition6.threshold=70 | ||||||
|  | Acquisition6.doppler_max=10000 | ||||||
|  | Acquisition6.doppler_step=250 | ||||||
|  | ;Acquisition6.satellite=22 | ||||||
|  | ;Acquisition6.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 7 CONFIG ############ | ||||||
|  | Acquisition7.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition7.threshold=70 | ||||||
|  | Acquisition7.doppler_max=10000 | ||||||
|  | Acquisition7.doppler_step=250 | ||||||
|  | ;Acquisition7.satellite=23 | ||||||
|  | ;Acquisition7.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### TRACKING GLOBAL CONFIG ############ | ||||||
|  |  | ||||||
|  | ;#implementatiion: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] | ||||||
|  | Tracking.implementation=GPS_L1_CA_DLL_FLL_PLL_Tracking | ||||||
|  |  | ||||||
|  | ;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. | ||||||
|  | Tracking.item_type=gr_complex | ||||||
|  |  | ||||||
|  | ;#sampling_frequency: Signal Intermediate Frequency in [Hz]  | ||||||
|  | Tracking.if=0 | ||||||
|  |  | ||||||
|  | ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]  | ||||||
|  | Tracking.dump=true | ||||||
|  |  | ||||||
|  | ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. | ||||||
|  | Tracking.dump_filename=./tracking_ch_ | ||||||
|  |  | ||||||
|  | ;#pll_bw_hz: PLL loop filter bandwidth [Hz] | ||||||
|  | Tracking.pll_bw_hz=50.0; | ||||||
|  |  | ||||||
|  | ;#dll_bw_hz: DLL loop filter bandwidth [Hz] | ||||||
|  | Tracking.dll_bw_hz=2.0; | ||||||
|  |  | ||||||
|  | ;#fll_bw_hz: FLL loop filter bandwidth [Hz] | ||||||
|  | Tracking.fll_bw_hz=20.0; | ||||||
|  |  | ||||||
|  | ;#order: PLL/DLL loop filter order [2] or [3] | ||||||
|  | Tracking.order=2; | ||||||
|  |  | ||||||
|  | ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] | ||||||
|  | Tracking.early_late_space_chips=0.5; | ||||||
|  |  | ||||||
|  | ;######### TELEMETRY DECODER CONFIG ############ | ||||||
|  | ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A. | ||||||
|  | TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder | ||||||
|  |  | ||||||
|  | ;#fs_in: Signal sampling frequency in [Hz]  | ||||||
|  | TelemetryDecoder.fs_in=4000000 | ||||||
|  |  | ||||||
|  | ;######### OBSERVABLES CONFIG ############ | ||||||
|  | ;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A. | ||||||
|  | Observables.implementation=GPS_L1_CA_Observables | ||||||
|  |  | ||||||
|  | ;#output_rate_ms: Period between two psudoranges outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms] | ||||||
|  | Observables.output_rate_ms=100 | ||||||
|  |  | ||||||
|  | ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false]  | ||||||
|  | Observables.dump=false | ||||||
|  |  | ||||||
|  | ;#dump_filename: Log path and filename. | ||||||
|  | Observables.dump_filename=./observables.dat | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ;######### PVT CONFIG ############ | ||||||
|  | ;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version. | ||||||
|  | PVT.implementation=GPS_L1_CA_PVT | ||||||
|  |  | ||||||
|  | ;#averaging_depth: Number of PVT observations in the moving average algorithm | ||||||
|  | PVT.averaging_depth=2 | ||||||
|  |  | ||||||
|  | ;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]  | ||||||
|  | PVT.flag_averaging=true | ||||||
|  |  | ||||||
|  | ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]  | ||||||
|  | PVT.dump=true | ||||||
|  |  | ||||||
|  | ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. | ||||||
|  | PVT.dump_filename=./PVT | ||||||
|  |  | ||||||
|  | ;######### OUTPUT_FILTER CONFIG ############ | ||||||
|  | ;# Receiver output filter: Leave this block disabled in this version | ||||||
|  | OutputFilter.implementation=Null_Sink_Output_Filter | ||||||
|  | OutputFilter.filename=data/gnss-sdr.dat | ||||||
|  | OutputFilter.item_type=gr_complex | ||||||
							
								
								
									
										223
									
								
								conf/master.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								conf/master.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,223 @@ | |||||||
|  | ; MASTER configuration file | ||||||
|  | ; This file should be updated with the latest changes in the configuration parameters, as a sample configuration file. | ||||||
|  | ; use RELATIVE file path in this configuration file | ||||||
|  | ; Sample for a configuration file for GNSS-SDR | ||||||
|  |  | ||||||
|  | [GNSS-SDR] | ||||||
|  |  | ||||||
|  | ;######### GLOBAL OPTIONS ################## | ||||||
|  | ;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. | ||||||
|  | GNSS-SDR.internal_fs_hz=4000000 | ||||||
|  |  | ||||||
|  | ;######### CONTROL_THREAD CONFIG ############ | ||||||
|  | ControlThread.wait_for_flowgraph=false | ||||||
|  |  | ||||||
|  | ;######### SIGNAL_SOURCE CONFIG ############ | ||||||
|  | ;#implementation: Use only File_Signal_Source in this version | ||||||
|  | SignalSource.implementation=File_Signal_Source | ||||||
|  |  | ||||||
|  | ;#filename: path to file with the captured GNSS signal samples to be processed | ||||||
|  | SignalSource.filename=../data/agilent_cap2.dat | ||||||
|  |  | ||||||
|  | ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. | ||||||
|  | SignalSource.item_type=gr_complex | ||||||
|  |  | ||||||
|  | ;#sampling_frequency: Original Signal sampling frequency in [Hz]  | ||||||
|  | SignalSource.sampling_frequency=4000000 | ||||||
|  |  | ||||||
|  | ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. | ||||||
|  | SignalSource.samples=0 | ||||||
|  |  | ||||||
|  | ;#repeat: Repeat the processing file. Disable this option in this version | ||||||
|  | SignalSource.repeat=false | ||||||
|  |  | ||||||
|  | ;#dump: Dump the Signal source data to a file. Disable this option in this version | ||||||
|  | SignalSource.dump=false | ||||||
|  |  | ||||||
|  | ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. | ||||||
|  | ; it helps to not overload the CPU, but the processing time will be longer.  | ||||||
|  | SignalSource.enable_throttle_control=false | ||||||
|  |  | ||||||
|  | ;######### SIGNAL_CONDITIONER CONFIG ############ | ||||||
|  | ;## Enables and configures a real-time resampler. Please disable it in this version. | ||||||
|  | ;implementation: Pass_Through disables this block | ||||||
|  | SignalConditioner.implementation=Pass_Through | ||||||
|  | SignalConditioner.item_type=gr_complex | ||||||
|  | SignalConditioner.sample_freq_in=4000000 | ||||||
|  | SignalConditioner.sample_freq_out=4000000 | ||||||
|  | SignalConditioner.dump=false | ||||||
|  |  | ||||||
|  | ;######### CHANNELS CONFIGURATION CONFIG ############ | ||||||
|  | ;#count: Number of avalable satellite channels. | ||||||
|  | Channels.count=4 | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION GLOBAL CONFIG ############ | ||||||
|  |  | ||||||
|  | ;#dump: Enable or disable the acquisition internal data file logging [true] or [false]  | ||||||
|  | Acquisition.dump=false | ||||||
|  |  | ||||||
|  | ;#filename: Log path and filename | ||||||
|  | Acquisition.dump_filename=./acq_dump.dat | ||||||
|  |  | ||||||
|  | ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. | ||||||
|  | Acquisition.item_type=gr_complex | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ;#if: Signal intermediate frequency in [Hz]  | ||||||
|  | Acquisition.if=0 | ||||||
|  |  | ||||||
|  | ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] | ||||||
|  | Acquisition.sampled_ms=1 | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CHANNELS CONFIG ###### | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 0 CONFIG ############ | ||||||
|  | ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] | ||||||
|  | Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  |  | ||||||
|  | ;#threshold: Acquisition threshold | ||||||
|  | Acquisition0.threshold=70 | ||||||
|  |  | ||||||
|  | ;#doppler_max: Maximum expected Doppler shift [Hz] | ||||||
|  | Acquisition0.doppler_max=10000 | ||||||
|  |  | ||||||
|  | ;#doppler_max: Doppler step in the grid search [Hz] | ||||||
|  | Acquisition0.doppler_step=250 | ||||||
|  |  | ||||||
|  | ;#satellite: Satellite PRN ID for this channel. Disable this option to random search | ||||||
|  | ;Acquisition0.satellite=14 | ||||||
|  |  | ||||||
|  | ;#repeat_satellite: Use only jointly with the satellte PRN ID option.  | ||||||
|  | ;#Enable repeat_satellite to keep searching the same satellite during the runtime. | ||||||
|  | ;Acquisition0.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 1 CONFIG ############ | ||||||
|  | Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition1.threshold=70 | ||||||
|  | Acquisition1.doppler_max=10000 | ||||||
|  | Acquisition1.doppler_step=250 | ||||||
|  | ;Acquisition1.satellite=32 | ||||||
|  | ;Acquisition1.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 2 CONFIG ############ | ||||||
|  | Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition2.threshold=70 | ||||||
|  | Acquisition2.doppler_max=10000 | ||||||
|  | Acquisition2.doppler_step=250 | ||||||
|  | ;Acquisition2.satellite=11 | ||||||
|  | ;Acquisition2.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 3 CONFIG ############ | ||||||
|  | Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition3.threshold=70 | ||||||
|  | Acquisition3.doppler_max=10000 | ||||||
|  | Acquisition3.doppler_step=250 | ||||||
|  | ;Acquisition3.satellite=1 | ||||||
|  | ;Acquisition3.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 4 CONFIG ############ | ||||||
|  | Acquisition4.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition4.threshold=70 | ||||||
|  | Acquisition4.doppler_max=10000 | ||||||
|  | Acquisition4.doppler_step=250 | ||||||
|  | ;Acquisition4.satellite=31 | ||||||
|  | ;Acquisition4.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 5 CONFIG ############ | ||||||
|  | Acquisition5.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition5.threshold=70 | ||||||
|  | Acquisition5.doppler_max=10000 | ||||||
|  | Acquisition5.doppler_step=250 | ||||||
|  | ;Acquisition5.satellite=20 | ||||||
|  | ;Acquisition5.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 6 CONFIG ############ | ||||||
|  | Acquisition6.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition6.threshold=70 | ||||||
|  | Acquisition6.doppler_max=10000 | ||||||
|  | Acquisition6.doppler_step=250 | ||||||
|  | ;Acquisition6.satellite=22 | ||||||
|  | ;Acquisition6.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### ACQUISITION CH 7 CONFIG ############ | ||||||
|  | Acquisition7.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
|  | Acquisition7.threshold=70 | ||||||
|  | Acquisition7.doppler_max=10000 | ||||||
|  | Acquisition7.doppler_step=250 | ||||||
|  | ;Acquisition7.satellite=23 | ||||||
|  | ;Acquisition7.repeat_satellite=true | ||||||
|  |  | ||||||
|  | ;######### TRACKING GLOBAL CONFIG ############ | ||||||
|  |  | ||||||
|  | ;#implementatiion: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] | ||||||
|  | Tracking.implementation=GPS_L1_CA_DLL_PLL_Tracking | ||||||
|  |  | ||||||
|  | ;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. | ||||||
|  | Tracking.item_type=gr_complex | ||||||
|  |  | ||||||
|  | ;#sampling_frequency: Signal Intermediate Frequency in [Hz]  | ||||||
|  | Tracking.if=0 | ||||||
|  |  | ||||||
|  | ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]  | ||||||
|  | Tracking.dump=false | ||||||
|  |  | ||||||
|  | ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. | ||||||
|  | Tracking.dump_filename=./tracking_ch_ | ||||||
|  |  | ||||||
|  | ;#pll_bw_hz: PLL loop filter bandwidth [Hz] | ||||||
|  | Tracking.pll_bw_hz=50.0; | ||||||
|  |  | ||||||
|  | ;#dll_bw_hz: DLL loop filter bandwidth [Hz] | ||||||
|  | Tracking.dll_bw_hz=2.0; | ||||||
|  |  | ||||||
|  | ;#fll_bw_hz: FLL loop filter bandwidth [Hz] | ||||||
|  | Tracking.fll_bw_hz=20.0; | ||||||
|  |  | ||||||
|  | ;#order: PLL/DLL loop filter order [2] or [3] | ||||||
|  | Tracking.order=2; | ||||||
|  |  | ||||||
|  | ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] | ||||||
|  | Tracking.early_late_space_chips=0.5; | ||||||
|  |  | ||||||
|  | ;######### TELEMETRY DECODER CONFIG ############ | ||||||
|  | ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A. | ||||||
|  | TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder | ||||||
|  |  | ||||||
|  | ;#fs_in: Signal sampling frequency in [Hz]  | ||||||
|  | TelemetryDecoder.fs_in=4000000 | ||||||
|  |  | ||||||
|  | ;######### OBSERVABLES CONFIG ############ | ||||||
|  | ;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A. | ||||||
|  | Observables.implementation=GPS_L1_CA_Observables | ||||||
|  |  | ||||||
|  | ;#output_rate_ms: Period between two psudoranges outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms] | ||||||
|  | Observables.output_rate_ms=100 | ||||||
|  |  | ||||||
|  | ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false]  | ||||||
|  | Observables.dump=false | ||||||
|  |  | ||||||
|  | ;#dump_filename: Log path and filename. | ||||||
|  | Observables.dump_filename=./observables.dat | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ;######### PVT CONFIG ############ | ||||||
|  | ;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version. | ||||||
|  | PVT.implementation=GPS_L1_CA_PVT | ||||||
|  |  | ||||||
|  | ;#averaging_depth: Number of PVT observations in the moving average algorithm | ||||||
|  | PVT.averaging_depth=2 | ||||||
|  |  | ||||||
|  | ;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]  | ||||||
|  | PVT.flag_averaging=true | ||||||
|  |  | ||||||
|  | ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]  | ||||||
|  | PVT.dump=true | ||||||
|  |  | ||||||
|  | ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. | ||||||
|  | PVT.dump_filename=./PVT | ||||||
|  |  | ||||||
|  | ;######### OUTPUT_FILTER CONFIG ############ | ||||||
|  | ;# Receiver output filter: Leave this block disabled in this version | ||||||
|  | OutputFilter.implementation=Null_Sink_Output_Filter | ||||||
|  | OutputFilter.filename=data/gnss-sdr.dat | ||||||
|  | OutputFilter.item_type=gr_complex | ||||||
| @@ -1,101 +0,0 @@ | |||||||
| ; Sample for a configuration file for MERCURIO |  | ||||||
|  |  | ||||||
| [mercurio] |  | ||||||
|  |  | ||||||
| ;######### CONTROL_THREAD CONFIG ############ |  | ||||||
| ControlThread.wait_for_flowgraph=false |  | ||||||
|  |  | ||||||
| ;######### SIGNAL_SOURCE CONFIG ############ |  | ||||||
| SignalSource.implementation=File_Signal_Source |  | ||||||
| ;SignalSource.filename=/media/DATALOGGER/signals/spirent scenario 2/data/sc2_d8.dat |  | ||||||
| ;SignalSource.filename=/media/My Passport/KINGSTON (G)/Project Luis/GPSL1_Fs_8MHz_ID_1_CN0_60.dat |  | ||||||
| SignalSource.filename=/media/DATALOGGER/signals/Agilent GPS Generator/cap2/agilent_cap2.dat |  | ||||||
| ;SignalSource.filename=/home/luis/Project/signals/GPS_L1_8sats_4_Msps_CN0_52.dat |  | ||||||
| SignalSource.item_type=gr_complex |  | ||||||
| SignalSource.sampling_frequency=4000000 |  | ||||||
| SignalSource.samples=292000000 |  | ||||||
| SignalSource.repeat=false |  | ||||||
| SignalSource.dump=false |  | ||||||
| SignalSource.enable_throttle_control=false |  | ||||||
|  |  | ||||||
| ;######### SIGNAL_CONDITIONER CONFIG ############ |  | ||||||
| SignalConditioner.implementation=Pass_Through |  | ||||||
| SignalConditioner.item_type=gr_complex |  | ||||||
| SignalConditioner.sample_freq_in=4000000 |  | ||||||
| SignalConditioner.sample_freq_out=4000000 |  | ||||||
| SignalConditioner.dump=false |  | ||||||
|  |  | ||||||
| ;######### CHANNELS CONFIGURATION CONFIG ############ |  | ||||||
| Channels.count=1 |  | ||||||
|  |  | ||||||
| ;######### ACQUISITION CONFIG ############ |  | ||||||
|  |  | ||||||
| Acquisition.dump=false |  | ||||||
| Acquisition.dump_filename=./acq_dump.dat |  | ||||||
| Acquisition.item_type=gr_complex |  | ||||||
| Acquisition.fs_in=4000000 |  | ||||||
| Acquisition.if=0 |  | ||||||
| Acquisition.sampled_ms=1 |  | ||||||
|  |  | ||||||
| ;######### ACQUISITION 0 CONFIG ############ |  | ||||||
| Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition |  | ||||||
| Acquisition0.threshold=440 |  | ||||||
| Acquisition0.doppler_max=10000 |  | ||||||
| Acquisition0.doppler_step=500 |  | ||||||
| Acquisition0.satellite=14 |  | ||||||
| Acquisition0.repeat_satellite=true |  | ||||||
|  |  | ||||||
| ;######### ACQUISITION 1 CONFIG ############ |  | ||||||
| Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition |  | ||||||
| Acquisition1.threshold=440 |  | ||||||
| Acquisition1.doppler_max=10000 |  | ||||||
| Acquisition1.doppler_step=500 |  | ||||||
| Acquisition1.satellite=1 |  | ||||||
| Acquisition1.repeat_satellite=true |  | ||||||
|  |  | ||||||
| ;######### ACQUISITION 2 CONFIG ############ |  | ||||||
| Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition |  | ||||||
| Acquisition2.threshold=440 |  | ||||||
| Acquisition2.doppler_max=10000 |  | ||||||
| Acquisition2.doppler_step=500 |  | ||||||
| Acquisition2.satellite=1 |  | ||||||
| Acquisition2.repeat_satellite=true |  | ||||||
|  |  | ||||||
| ;######### ACQUISITION 3 CONFIG ############ |  | ||||||
| Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition |  | ||||||
| Acquisition3.threshold=440 |  | ||||||
| Acquisition3.doppler_max=10000 |  | ||||||
| Acquisition3.doppler_step=500 |  | ||||||
| Acquisition3.satellite=1 |  | ||||||
| Acquisition3.repeat_satellite=true |  | ||||||
| 	 |  | ||||||
| ;######### TRACKING CONFIG ############ |  | ||||||
| ;Tracking.implementation=GPS_L1_CA_DLL_PLL_Tracking |  | ||||||
| Tracking.implementation=GPS_L1_CA_DLL_FLL_PLL_Tracking |  | ||||||
| Tracking.item_type=gr_complex |  | ||||||
| Tracking.vector_length=4000 |  | ||||||
| Tracking.fs_in=4000000 |  | ||||||
| Tracking.if=0 |  | ||||||
| Tracking.dump=true |  | ||||||
| Tracking.pll_bw_hz=50.0; |  | ||||||
| Tracking.dll_bw_hz=2.0; |  | ||||||
| Tracking.fll_bw_hz=50; |  | ||||||
| Tracking.order=2; |  | ||||||
| Tracking.early_late_space_chips=0.5; |  | ||||||
|  |  | ||||||
| ;######### TELEMETRY DECODER CONFIG ############ |  | ||||||
| TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder |  | ||||||
| TelemetryDecoder.item_type=gr_complex |  | ||||||
|  |  | ||||||
| ;######### OBSERVABLES CONFIG ############ |  | ||||||
| Observables.implementation=GPS_L1_CA_Observables |  | ||||||
| Observables.fs_in=4000000; |  | ||||||
|  |  | ||||||
| ;######### PVT CONFIG ############ |  | ||||||
| PVT.implementation=Pass_Through |  | ||||||
| PVT.item_type=gr_complex |  | ||||||
|  |  | ||||||
| ;######### OUTPUT_FILTER CONFIG ############ |  | ||||||
| OutputFilter.implementation=Null_Sink_Output_Filter |  | ||||||
| OutputFilter.filename=data/mercurio.dat |  | ||||||
| OutputFilter.item_type=gr_complex |  | ||||||
| @@ -29,11 +29,11 @@ project : requirements | |||||||
| <include>src/algorithms/libs | <include>src/algorithms/libs | ||||||
| <include>src/algorithms/observables/adapters | <include>src/algorithms/observables/adapters | ||||||
| <include>src/algorithms/observables/gnuradio_blocks | <include>src/algorithms/observables/gnuradio_blocks | ||||||
| <include>src/algorithms/observables/libs |  | ||||||
| <include>src/algorithms/output_filter/adapters | <include>src/algorithms/output_filter/adapters | ||||||
| <include>src/algorithms/output_filter/gnuradio_blocks | <include>src/algorithms/output_filter/gnuradio_blocks | ||||||
| <include>src/algorithms/PVT/adapters | <include>src/algorithms/PVT/adapters | ||||||
| <include>src/algorithms/PVT/gnuradio_blocks | <include>src/algorithms/PVT/gnuradio_blocks | ||||||
|  | <include>src/algorithms/PVT/libs | ||||||
| <include>src/algorithms/signal_source/adapters | <include>src/algorithms/signal_source/adapters | ||||||
| <include>src/algorithms/signal_source/gnuradio_blocks | <include>src/algorithms/signal_source/gnuradio_blocks | ||||||
| <include>src/algorithms/telemetry_decoder/adapters | <include>src/algorithms/telemetry_decoder/adapters | ||||||
|   | |||||||
							
								
								
									
										103
									
								
								src/algorithms/PVT/adapters/gps_l1_ca_pvt.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/algorithms/PVT/adapters/gps_l1_ca_pvt.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | |||||||
|  | /*! | ||||||
|  |  * \file gps_l1_ca_pvt.cc | ||||||
|  |  * \brief Simple Least Squares implementation for GPS L1 C/A Position Velocity and Time | ||||||
|  |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "gps_l1_ca_pvt.h" | ||||||
|  | #include "configuration_interface.h" | ||||||
|  | #include "gps_l1_ca_pvt_cc.h" | ||||||
|  | #include <gnuradio/gr_io_signature.h> | ||||||
|  | #include <glog/log_severity.h> | ||||||
|  | #include <glog/logging.h> | ||||||
|  |  | ||||||
|  | extern concurrent_queue<gps_navigation_message> global_gps_nav_msg_queue; | ||||||
|  |  | ||||||
|  | using google::LogMessage; | ||||||
|  |  | ||||||
|  | GpsL1CaPvt::GpsL1CaPvt(ConfigurationInterface* configuration, | ||||||
|  |         std::string role, | ||||||
|  |         unsigned int in_streams, | ||||||
|  |         unsigned int out_streams, | ||||||
|  |         gr_msg_queue_sptr queue) : | ||||||
|  |         role_(role), | ||||||
|  |         in_streams_(in_streams), | ||||||
|  |         out_streams_(out_streams), | ||||||
|  |         queue_(queue) | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     std::string default_dump_filename = "./pvt.dat"; | ||||||
|  |  | ||||||
|  |     DLOG(INFO) << "role " << role; | ||||||
|  |  | ||||||
|  | 	int averaging_depth; | ||||||
|  | 	averaging_depth=configuration->property(role + ".averaging_depth", 10); | ||||||
|  |  | ||||||
|  |     bool flag_averaging; | ||||||
|  |     flag_averaging=configuration->property(role + ".flag_averaging", false); | ||||||
|  |  | ||||||
|  |     dump_ = configuration->property(role + ".dump", false); | ||||||
|  |     dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); | ||||||
|  |  | ||||||
|  | 	pvt_ = gps_l1_ca_make_pvt_cc(in_streams_, queue_, dump_, dump_filename_, averaging_depth, flag_averaging); | ||||||
|  |  | ||||||
|  |     DLOG(INFO) << "pvt(" << pvt_->unique_id() << ")"; | ||||||
|  |     // set the navigation msg queue; | ||||||
|  |  | ||||||
|  |     pvt_->set_navigation_queue(&global_gps_nav_msg_queue); | ||||||
|  |  | ||||||
|  |     DLOG(INFO) << "global navigation message queue assigned to pvt ("<< pvt_->unique_id() << ")"; | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | GpsL1CaPvt::~GpsL1CaPvt() | ||||||
|  | {} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void GpsL1CaPvt::connect(gr_top_block_sptr top_block) | ||||||
|  | { | ||||||
|  |     // Nothing to connect internally | ||||||
|  |     DLOG(INFO) << "nothing to connect internally"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GpsL1CaPvt::disconnect(gr_top_block_sptr top_block) | ||||||
|  | { | ||||||
|  |     // Nothing to disconnect | ||||||
|  | } | ||||||
|  |  | ||||||
|  | gr_basic_block_sptr GpsL1CaPvt::get_left_block() | ||||||
|  | { | ||||||
|  |     return pvt_; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | gr_basic_block_sptr GpsL1CaPvt::get_right_block() | ||||||
|  | { | ||||||
|  |     return pvt_; | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										94
									
								
								src/algorithms/PVT/adapters/gps_l1_ca_pvt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/algorithms/PVT/adapters/gps_l1_ca_pvt.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | /*! | ||||||
|  |  * \file gps_l1_ca_pvt.h | ||||||
|  |  * \brief Simple Least Squares implementation for GPS L1 C/A Position Velocity and Time | ||||||
|  |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifndef GPS_L1_CA_PVT_H_ | ||||||
|  | #define GPS_L1_CA_PVT_H_ | ||||||
|  |  | ||||||
|  | #include "pvt_interface.h" | ||||||
|  |  | ||||||
|  | #include "gps_l1_ca_pvt_cc.h" | ||||||
|  |  | ||||||
|  | #include <gnuradio/gr_msg_queue.h> | ||||||
|  |  | ||||||
|  | class ConfigurationInterface; | ||||||
|  |  | ||||||
|  | class GpsL1CaPvt : public PvtInterface | ||||||
|  | { | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |  | ||||||
|  | 	GpsL1CaPvt(ConfigurationInterface* configuration, | ||||||
|  |             std::string role, | ||||||
|  |             unsigned int in_streams, | ||||||
|  |             unsigned int out_streams, | ||||||
|  |             gr_msg_queue_sptr queue); | ||||||
|  |  | ||||||
|  |     virtual ~GpsL1CaPvt(); | ||||||
|  |  | ||||||
|  |     std::string role() | ||||||
|  |     { | ||||||
|  |         return role_; | ||||||
|  |     } | ||||||
|  |     std::string implementation() | ||||||
|  |     { | ||||||
|  |         return "pvt"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void connect(gr_top_block_sptr top_block); | ||||||
|  |     void disconnect(gr_top_block_sptr top_block); | ||||||
|  |     gr_basic_block_sptr get_left_block(); | ||||||
|  |     gr_basic_block_sptr get_right_block(); | ||||||
|  |  | ||||||
|  |     void reset() | ||||||
|  |     { | ||||||
|  |         return; | ||||||
|  |     }; | ||||||
|  |     // all blocks must have an intem_size() function implementation | ||||||
|  |     size_t item_size() | ||||||
|  |     { | ||||||
|  |         return sizeof(gr_complex); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |  | ||||||
|  |     gps_l1_ca_pvt_cc_sptr pvt_; | ||||||
|  |     bool dump_; | ||||||
|  |     unsigned int fs_in_; | ||||||
|  |     std::string dump_filename_; | ||||||
|  |     std::string role_; | ||||||
|  |     unsigned int in_streams_; | ||||||
|  |     unsigned int out_streams_; | ||||||
|  |     gr_msg_queue_sptr queue_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif | ||||||
							
								
								
									
										3
									
								
								src/algorithms/PVT/adapters/jamfile.jam
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/algorithms/PVT/adapters/jamfile.jam
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | project : build-dir ../../../../build ; | ||||||
|  |  | ||||||
|  | obj gps_l1_ca_pvt : gps_l1_ca_pvt.cc ; | ||||||
							
								
								
									
										167
									
								
								src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | |||||||
|  | /*! | ||||||
|  |  * \file gps_l1_ca_pvt_cc.cc | ||||||
|  |  * \brief Position Velocity and Time computation for GPS L1 C/A using Least Squares algorithm | ||||||
|  |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <iostream> | ||||||
|  | #include <sstream> | ||||||
|  | #include <vector> | ||||||
|  | #include <map> | ||||||
|  | #include <algorithm> | ||||||
|  | #include <bitset> | ||||||
|  |  | ||||||
|  | #include <cmath> | ||||||
|  | #include "math.h" | ||||||
|  |  | ||||||
|  | #include "gps_l1_ca_pvt_cc.h" | ||||||
|  |  | ||||||
|  | #include "control_message_factory.h" | ||||||
|  |  | ||||||
|  | #include <gnuradio/gr_io_signature.h> | ||||||
|  |  | ||||||
|  | #include <glog/log_severity.h> | ||||||
|  | #include <glog/logging.h> | ||||||
|  |  | ||||||
|  | using google::LogMessage; | ||||||
|  |  | ||||||
|  | using namespace std; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | gps_l1_ca_pvt_cc_sptr | ||||||
|  | gps_l1_ca_make_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging) { | ||||||
|  |  | ||||||
|  |   return gps_l1_ca_pvt_cc_sptr(new gps_l1_ca_pvt_cc(nchannels, queue, dump, dump_filename, averaging_depth, flag_averaging)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging) : | ||||||
|  | 		        gr_block ("gps_l1_ca_pvt_cc", gr_make_io_signature (nchannels, nchannels,  sizeof(gnss_pseudorange)), | ||||||
|  | 		            gr_make_io_signature(1, 1, sizeof(gr_complex))) { | ||||||
|  |  | ||||||
|  |   // initialize internal vars | ||||||
|  |   d_queue = queue; | ||||||
|  |   d_dump = dump; | ||||||
|  |   d_nchannels = nchannels; | ||||||
|  |   d_dump_filename=dump_filename; | ||||||
|  |   std::string kml_dump_filename; | ||||||
|  |   kml_dump_filename=d_dump_filename; | ||||||
|  |   kml_dump_filename.append(".kml"); | ||||||
|  |   d_kml_dump.set_headers(kml_dump_filename); | ||||||
|  |   d_dump_filename.append(".dat"); | ||||||
|  |  | ||||||
|  |   d_averaging_depth=averaging_depth; | ||||||
|  |   d_flag_averaging=flag_averaging; | ||||||
|  |   /*! | ||||||
|  |    * \todo Enable RINEX printer: The actual RINEX printer need a complete refactoring and some bug fixing work | ||||||
|  |    */ | ||||||
|  |   //d_rinex_printer.set_headers("GNSS-SDR"); | ||||||
|  |   d_ls_pvt=new gps_l1_ca_ls_pvt(nchannels,d_dump_filename,d_dump); | ||||||
|  |   d_ls_pvt->set_averaging_depth(d_averaging_depth); | ||||||
|  |   d_ephemeris_clock_s=0.0; | ||||||
|  |  | ||||||
|  |   d_sample_counter=0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | gps_l1_ca_pvt_cc::~gps_l1_ca_pvt_cc() { | ||||||
|  |     d_kml_dump.close_file(); | ||||||
|  |     delete d_ls_pvt; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool pseudoranges_pairCompare_min( pair<int,gnss_pseudorange> a, pair<int,gnss_pseudorange> b) | ||||||
|  | { | ||||||
|  |   return (a.second.pseudorange_m) < (b.second.pseudorange_m); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_items, | ||||||
|  | 		gr_vector_const_void_star &input_items,	gr_vector_void_star &output_items) { | ||||||
|  |  | ||||||
|  | 	d_sample_counter++; | ||||||
|  |  | ||||||
|  | 	map<int,gnss_pseudorange> gnss_pseudoranges_map; | ||||||
|  | 	map<int,gnss_pseudorange>::iterator gnss_pseudoranges_iter; | ||||||
|  |  | ||||||
|  | 	gnss_pseudorange **in = (gnss_pseudorange **)  &input_items[0]; //Get the input pointer | ||||||
|  |  | ||||||
|  | 	for (unsigned int i=0;i<d_nchannels;i++) | ||||||
|  | 	{ | ||||||
|  | 		if (in[i][0].valid==true) | ||||||
|  | 		{ | ||||||
|  | 			gnss_pseudoranges_map.insert(pair<int,gnss_pseudorange>(in[i][0].SV_ID,in[i][0])); //record the valid psudorrange in a map | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	//debug print | ||||||
|  | 	cout << setprecision(16); | ||||||
|  | 	for(gnss_pseudoranges_iter = gnss_pseudoranges_map.begin(); | ||||||
|  | 			gnss_pseudoranges_iter != gnss_pseudoranges_map.end(); | ||||||
|  | 			gnss_pseudoranges_iter++) | ||||||
|  | 	{ | ||||||
|  | 		cout<<"Pseudoranges(SV ID,pseudorange [m]) =("<<gnss_pseudoranges_iter->first<<","<<gnss_pseudoranges_iter->second.pseudorange_m<<")"<<endl; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	// ############ 1. READ EPHEMERIS FROM QUEUE ###################### | ||||||
|  |     // find the minimum index (nearest satellite, will be the reference) | ||||||
|  | 	gnss_pseudoranges_iter=min_element(gnss_pseudoranges_map.begin(),gnss_pseudoranges_map.end(),pseudoranges_pairCompare_min); | ||||||
|  |  | ||||||
|  | 	gps_navigation_message nav_msg; | ||||||
|  | 	while (d_nav_queue->try_pop(nav_msg)==true) | ||||||
|  | 	{ | ||||||
|  | 		cout<<"New ephemeris record has arrived from SAT ID "<<nav_msg.d_satellite_PRN<<endl; | ||||||
|  | 		d_last_nav_msg=nav_msg; | ||||||
|  | 		d_ls_pvt->d_ephemeris[nav_msg.d_channel_ID]=nav_msg; | ||||||
|  | 		// **** update pseudoranges clock **** | ||||||
|  | 		if (nav_msg.d_satellite_PRN==gnss_pseudoranges_iter->second.SV_ID) | ||||||
|  | 		{ | ||||||
|  | 			d_ephemeris_clock_s=d_last_nav_msg.d_TOW; | ||||||
|  | 			d_ephemeris_timestamp_ms=d_last_nav_msg.d_subframe1_timestamp_ms; | ||||||
|  | 		} | ||||||
|  | 		// **** write ephemeris to RINES NAV file | ||||||
|  | 		//d_rinex_printer.LogRinex2Nav(nav_msg); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// ############ 2. COMPUTE THE PVT ################################ | ||||||
|  | 	// write the pseudoranges to RINEX OBS file | ||||||
|  | 	// 1- need a valid clock | ||||||
|  | 	if (d_ephemeris_clock_s>0 and d_last_nav_msg.d_satellite_PRN>0) | ||||||
|  | 	{ | ||||||
|  | 		//d_rinex_printer.LogRinex2Obs(d_last_nav_msg,d_ephemeris_clock_s+((double)pseudoranges_timestamp_ms-d_ephemeris_timestamp_ms)/1000.0,pseudoranges); | ||||||
|  | 		// compute on the fly PVT solution | ||||||
|  | 		//std::cout<<"diff_clock_ephemerids="<<(gnss_pseudoranges_iter->second.timestamp_ms-d_ephemeris_timestamp_ms)/1000.0<<"\r\n"; | ||||||
|  | 		if (d_ls_pvt->get_PVT(gnss_pseudoranges_map, | ||||||
|  | 				d_ephemeris_clock_s+(gnss_pseudoranges_iter->second.timestamp_ms-d_ephemeris_timestamp_ms)/1000.0, | ||||||
|  | 				d_flag_averaging)==true) | ||||||
|  | 		{ | ||||||
|  | 			d_kml_dump.print_position(d_ls_pvt,d_flag_averaging); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	consume_each(1); //one by one | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										101
									
								
								src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | |||||||
|  | /*! | ||||||
|  |  * \file gps_l1_ca_pvt_cc.h | ||||||
|  |  * \brief Position Velocity and Time computation for GPS L1 C/A using Least Squares algorithm | ||||||
|  |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef GPS_L1_CA_PVT_CC_H | ||||||
|  | #define	GPS_L1_CA_PVT_CC_H | ||||||
|  |  | ||||||
|  | #include <fstream> | ||||||
|  |  | ||||||
|  | #include <gnuradio/gr_block.h> | ||||||
|  | #include <gnuradio/gr_msg_queue.h> | ||||||
|  |  | ||||||
|  | #include <queue> | ||||||
|  | #include <boost/thread/mutex.hpp> | ||||||
|  | #include <boost/thread/thread.hpp> | ||||||
|  |  | ||||||
|  | #include "concurrent_queue.h" | ||||||
|  |  | ||||||
|  | #include "gps_navigation_message.h" | ||||||
|  | #include "kml_printer.h" | ||||||
|  |  | ||||||
|  | #include "rinex_2_1_printer.h" | ||||||
|  | #include "gps_l1_ca_ls_pvt.h" | ||||||
|  |  | ||||||
|  | #include "GPS_L1_CA.h" | ||||||
|  |  | ||||||
|  | class gps_l1_ca_pvt_cc; | ||||||
|  | typedef boost::shared_ptr<gps_l1_ca_pvt_cc> gps_l1_ca_pvt_cc_sptr; | ||||||
|  | gps_l1_ca_pvt_cc_sptr | ||||||
|  | gps_l1_ca_make_pvt_cc(unsigned int n_channels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class gps_l1_ca_pvt_cc : public gr_block { | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |  | ||||||
|  |   friend gps_l1_ca_pvt_cc_sptr | ||||||
|  |   gps_l1_ca_make_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging); | ||||||
|  |  | ||||||
|  |   gps_l1_ca_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging); | ||||||
|  |  | ||||||
|  |   // class private vars | ||||||
|  |   gr_msg_queue_sptr d_queue; | ||||||
|  |   bool d_dump; | ||||||
|  |  | ||||||
|  |   unsigned int d_nchannels; | ||||||
|  |  | ||||||
|  |   std::string d_dump_filename; | ||||||
|  |   std::ofstream d_dump_file; | ||||||
|  |  | ||||||
|  |   int d_averaging_depth; | ||||||
|  |   bool d_flag_averaging; | ||||||
|  |  | ||||||
|  |   long unsigned int d_sample_counter; | ||||||
|  |  | ||||||
|  |   kml_printer d_kml_dump; | ||||||
|  |  | ||||||
|  |   concurrent_queue<gps_navigation_message> *d_nav_queue; // Navigation ephemeris queue | ||||||
|  |   gps_navigation_message d_last_nav_msg; //last navigation message | ||||||
|  |  | ||||||
|  |   double d_ephemeris_clock_s; | ||||||
|  |   double d_ephemeris_timestamp_ms; | ||||||
|  |   gps_l1_ca_ls_pvt *d_ls_pvt; | ||||||
|  |   //rinex_printer d_rinex_printer; // RINEX printer class | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |  | ||||||
|  |   ~gps_l1_ca_pvt_cc (); | ||||||
|  |  | ||||||
|  |   void set_navigation_queue(concurrent_queue<gps_navigation_message> *nav_queue){d_nav_queue=nav_queue;} | ||||||
|  |  | ||||||
|  |   int general_work (int noutput_items, gr_vector_int &ninput_items, | ||||||
|  |       gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif | ||||||
							
								
								
									
										3
									
								
								src/algorithms/PVT/gnuradio_blocks/jamfile.jam
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/algorithms/PVT/gnuradio_blocks/jamfile.jam
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | project : build-dir ../../../../build ; | ||||||
|  |  | ||||||
|  | obj gps_l1_ca_pvt_cc : gps_l1_ca_pvt_cc.cc ; | ||||||
							
								
								
									
										3
									
								
								src/algorithms/PVT/jamfile.jam
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/algorithms/PVT/jamfile.jam
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | build-project adapters ; | ||||||
|  | build-project gnuradio_blocks ; | ||||||
|  | build-project libs ; | ||||||
| @@ -46,16 +46,43 @@ | |||||||
| 
 | 
 | ||||||
| #include "gps_l1_ca_ls_pvt.h" | #include "gps_l1_ca_ls_pvt.h" | ||||||
| 
 | 
 | ||||||
| gps_l1_ca_ls_pvt::gps_l1_ca_ls_pvt(int nchannels) | 
 | ||||||
|  | gps_l1_ca_ls_pvt::gps_l1_ca_ls_pvt(int nchannels,std::string dump_filename, bool flag_dump_to_file) | ||||||
| { | { | ||||||
|     // init empty ephemerids for all the available GNSS channels
 |     // init empty ephemerids for all the available GNSS channels
 | ||||||
|     d_nchannels=nchannels; |     d_nchannels=nchannels; | ||||||
|     d_ephemeris=new gps_navigation_message[nchannels]; |     d_ephemeris=new gps_navigation_message[nchannels]; | ||||||
|  |     d_dump_filename=dump_filename; | ||||||
|  |     d_flag_dump_enabled=flag_dump_to_file; | ||||||
|  |     d_averaging_depth=0; | ||||||
|  | 
 | ||||||
|  | 	// ############# ENABLE DATA FILE LOG #################
 | ||||||
|  | 	if (d_flag_dump_enabled==true) | ||||||
|  | 	{ | ||||||
|  | 		if (d_dump_file.is_open()==false) | ||||||
|  | 		{ | ||||||
|  | 			try { | ||||||
|  | 				d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit ); | ||||||
|  | 				d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); | ||||||
|  | 				std::cout<<"PVT lib dump enabled Log file: "<<d_dump_filename.c_str()<<std::endl; | ||||||
|  | 			} | ||||||
|  | 			catch (std::ifstream::failure e) { | ||||||
|  | 				std::cout << "Exception opening PVT lib dump file "<<e.what()<<"\r\n"; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void gps_l1_ca_ls_pvt::set_averaging_depth(int depth) | ||||||
|  | { | ||||||
|  | 	d_averaging_depth=depth; | ||||||
|  | } | ||||||
| gps_l1_ca_ls_pvt::~gps_l1_ca_ls_pvt() | gps_l1_ca_ls_pvt::~gps_l1_ca_ls_pvt() | ||||||
| { | { | ||||||
|     delete d_ephemeris; | 	d_dump_file.close(); | ||||||
|  |     delete[] d_ephemeris; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| arma::vec gps_l1_ca_ls_pvt::e_r_corr(double traveltime, arma::vec X_sat) { | arma::vec gps_l1_ca_ls_pvt::e_r_corr(double traveltime, arma::vec X_sat) { | ||||||
| @@ -205,9 +232,9 @@ arma::vec gps_l1_ca_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arma | |||||||
|     return pos; |     return pos; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void gps_l1_ca_ls_pvt::get_PVT(std::map<int,float> pseudoranges,double GPS_current_time) | bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,gnss_pseudorange> gnss_pseudoranges_map,double GPS_current_time,bool flag_averaging) | ||||||
| { | { | ||||||
|     std::map<int,float>::iterator pseudoranges_iter; |     std::map<int,gnss_pseudorange>::iterator gnss_pseudoranges_iter; | ||||||
|     //ITPP
 |     //ITPP
 | ||||||
|     //mat W=eye(d_nchannels); //channels weights matrix
 |     //mat W=eye(d_nchannels); //channels weights matrix
 | ||||||
|     //vec obs=zeros(d_nchannels); // pseudoranges observation vector
 |     //vec obs=zeros(d_nchannels); // pseudoranges observation vector
 | ||||||
| @@ -223,10 +250,13 @@ void gps_l1_ca_ls_pvt::get_PVT(std::map<int,float> pseudoranges,double GPS_curre | |||||||
|     { |     { | ||||||
|         if (d_ephemeris[i].satellite_validation()==true) |         if (d_ephemeris[i].satellite_validation()==true) | ||||||
|         { |         { | ||||||
|             pseudoranges_iter=pseudoranges.find(d_ephemeris[i].d_satellite_PRN); |         	gnss_pseudoranges_iter=gnss_pseudoranges_map.find(d_ephemeris[i].d_satellite_PRN); | ||||||
|             if (pseudoranges_iter!=pseudoranges.end()) |             if (gnss_pseudoranges_iter!=gnss_pseudoranges_map.end()) | ||||||
|             { |             { | ||||||
|                 W(i,i)=1; // TODO: Place here the satellite CN0 (power level, or weight factor)
 |             	 /*!
 | ||||||
|  |             	  * \todo Place here the satellite CN0 (power level, or weight factor) | ||||||
|  |             	  */ | ||||||
|  |                 W(i,i)=1; | ||||||
|                 // compute the GPS master clock
 |                 // compute the GPS master clock
 | ||||||
|                 d_ephemeris[i].master_clock(GPS_current_time); |                 d_ephemeris[i].master_clock(GPS_current_time); | ||||||
|                 // compute the satellite current ECEF position
 |                 // compute the satellite current ECEF position
 | ||||||
| @@ -236,7 +266,9 @@ void gps_l1_ca_ls_pvt::get_PVT(std::map<int,float> pseudoranges,double GPS_curre | |||||||
|                 satpos(0,i)=d_ephemeris[i].d_satpos_X; |                 satpos(0,i)=d_ephemeris[i].d_satpos_X; | ||||||
|                 satpos(1,i)=d_ephemeris[i].d_satpos_Y; |                 satpos(1,i)=d_ephemeris[i].d_satpos_Y; | ||||||
|                 satpos(2,i)=d_ephemeris[i].d_satpos_Z; |                 satpos(2,i)=d_ephemeris[i].d_satpos_Z; | ||||||
|                 obs(i)=pseudoranges_iter->second+d_ephemeris[i].d_satClkCorr*GPS_C_m_s; |                 std::cout<<"ECEF satellite SV ID="<<d_ephemeris[i].d_satellite_PRN<<" X="<<d_ephemeris[i].d_satpos_X | ||||||
|  |                 		<<" [m] Y="<<d_ephemeris[i].d_satpos_Y<<" [m] Z="<<d_ephemeris[i].d_satpos_Z<<" [m]\r\n"; | ||||||
|  |                 obs(i)=gnss_pseudoranges_iter->second.pseudorange_m+d_ephemeris[i].d_satClkCorr*GPS_C_m_s; | ||||||
|                 valid_obs++; |                 valid_obs++; | ||||||
|             }else{ |             }else{ | ||||||
|                 // no valid pseudorange for the current channel
 |                 // no valid pseudorange for the current channel
 | ||||||
| @@ -254,9 +286,101 @@ void gps_l1_ca_ls_pvt::get_PVT(std::map<int,float> pseudoranges,double GPS_curre | |||||||
|     { |     { | ||||||
|         arma::vec mypos; |         arma::vec mypos; | ||||||
|         mypos=leastSquarePos(satpos,obs,W); |         mypos=leastSquarePos(satpos,obs,W); | ||||||
|         std::cout << "Position ("<<GPS_current_time<<") ECEF = " << mypos << std::endl; |         std::cout << "Position at TOW="<<GPS_current_time<<" is ECEF (X,Y,Z) = " << mypos << std::endl; | ||||||
|         cart2geo(mypos(0), mypos(1), mypos(2), 4); |         cart2geo(mypos(0), mypos(1), mypos(2), 4); | ||||||
|         std::cout << "Position ("<<GPS_current_time<<") Lat = " << d_latitude_d << " Long ="<< d_longitude_d <<" Height="<<d_height_m<< std::endl; |         std::cout << "Position at TOW="<<GPS_current_time<<" is Lat = " << d_latitude_d << " [º] Long ="<< d_longitude_d <<" [º] Height="<<d_height_m<<" [m]\r\n"; | ||||||
|  |         // ######## LOG FILE #########
 | ||||||
|  |     	if(d_flag_dump_enabled==true) { | ||||||
|  |     		// MULTIPLEXED FILE RECORDING - Record results to file
 | ||||||
|  |         	try { | ||||||
|  | 				double tmp_double; | ||||||
|  | 				//  PVT GPS time
 | ||||||
|  | 				tmp_double=GPS_current_time; | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// ECEF User Position East [m]
 | ||||||
|  | 				tmp_double=mypos(0); | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// ECEF User Position North [m]
 | ||||||
|  | 				tmp_double=mypos(1); | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// ECEF User Position Up [m]
 | ||||||
|  | 				tmp_double=mypos(2); | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// User clock offset [s]
 | ||||||
|  | 				tmp_double=mypos(3); | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// GEO user position Latitude [deg]
 | ||||||
|  | 				tmp_double=d_latitude_d; | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// GEO user position Longitude [deg]
 | ||||||
|  | 				tmp_double=d_longitude_d; | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// GEO user position Height [m]
 | ||||||
|  | 				tmp_double=d_height_m; | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  |         	} | ||||||
|  |     		  catch (std::ifstream::failure e) { | ||||||
|  |     			std::cout << "Exception writing PVT lib dump file "<<e.what()<<"\r\n"; | ||||||
|  |     		} | ||||||
|  |     	} | ||||||
|  | 
 | ||||||
|  |     	// MOVING AVERAGE PVT
 | ||||||
|  |     	if (flag_averaging==true) | ||||||
|  |     	{ | ||||||
|  |     		if (d_hist_longitude_d.size()==(unsigned int)d_averaging_depth) | ||||||
|  |     		{ | ||||||
|  |     			// Pop oldest value
 | ||||||
|  |         		d_hist_longitude_d.pop_back(); | ||||||
|  |         		d_hist_latitude_d.pop_back(); | ||||||
|  |         		d_hist_height_m.pop_back(); | ||||||
|  |         		// Push new values
 | ||||||
|  |         		d_hist_longitude_d.push_front(d_longitude_d); | ||||||
|  |         		d_hist_latitude_d.push_front(d_latitude_d); | ||||||
|  |         		d_hist_height_m.push_front(d_height_m); | ||||||
|  | 
 | ||||||
|  |     			d_avg_latitude_d=0; | ||||||
|  |     			d_avg_longitude_d=0; | ||||||
|  |     			d_avg_height_m=0; | ||||||
|  |     		    for (unsigned int i=0;i<d_hist_longitude_d.size();i++) | ||||||
|  |     		    { | ||||||
|  |     		    	d_avg_latitude_d=d_avg_latitude_d+d_hist_latitude_d.at(i); | ||||||
|  |     		        d_avg_longitude_d=d_avg_longitude_d+d_hist_longitude_d.at(i); | ||||||
|  |     		    	d_avg_height_m=d_avg_height_m+d_hist_height_m.at(i); | ||||||
|  |     		    } | ||||||
|  |     		    d_avg_latitude_d=d_avg_latitude_d/(double)d_averaging_depth; | ||||||
|  |     		    d_avg_longitude_d=d_avg_longitude_d/(double)d_averaging_depth; | ||||||
|  |     		    d_avg_height_m=d_avg_height_m/(double)d_averaging_depth; | ||||||
|  |     		    return true; //indicates that the returned position is valid
 | ||||||
|  |     		}else{ | ||||||
|  |     			//int current_depth=d_hist_longitude_d.size();
 | ||||||
|  |         		// Push new values
 | ||||||
|  |         		d_hist_longitude_d.push_front(d_longitude_d); | ||||||
|  |         		d_hist_latitude_d.push_front(d_latitude_d); | ||||||
|  |         		d_hist_height_m.push_front(d_height_m); | ||||||
|  | 
 | ||||||
|  |         		d_avg_latitude_d=d_latitude_d; | ||||||
|  |         		d_avg_longitude_d=d_longitude_d; | ||||||
|  |         		d_avg_height_m=d_height_m; | ||||||
|  | 				return false;//indicates that the returned position is not valid yet
 | ||||||
|  |         		// output the average, although it will not have the full historic available
 | ||||||
|  | //    			d_avg_latitude_d=0;
 | ||||||
|  | //    			d_avg_longitude_d=0;
 | ||||||
|  | //    			d_avg_height_m=0;
 | ||||||
|  | //    		    for (unsigned int i=0;i<d_hist_longitude_d.size();i++)
 | ||||||
|  | //    		    {
 | ||||||
|  | //    		    	d_avg_latitude_d=d_avg_latitude_d+d_hist_latitude_d.at(i);
 | ||||||
|  | //    		        d_avg_longitude_d=d_avg_longitude_d+d_hist_longitude_d.at(i);
 | ||||||
|  | //    		    	d_avg_height_m=d_avg_height_m+d_hist_height_m.at(i);
 | ||||||
|  | //    		    }
 | ||||||
|  | //    		    d_avg_latitude_d=d_avg_latitude_d/(double)current_depth;
 | ||||||
|  | //    		    d_avg_longitude_d=d_avg_longitude_d/(double)current_depth;
 | ||||||
|  | //    		    d_avg_height_m=d_avg_height_m/(double)current_depth;
 | ||||||
|  |     		} | ||||||
|  |     	}else{ | ||||||
|  |     		return true;//indicates that the returned position is valid
 | ||||||
|  |     	} | ||||||
|  |     }else{ | ||||||
|  |     	return false; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| void gps_l1_ca_ls_pvt::cart2geo(double X, double Y, double Z, int elipsoid_selection) | void gps_l1_ca_ls_pvt::cart2geo(double X, double Y, double Z, int elipsoid_selection) | ||||||
| @@ -30,6 +30,7 @@ | |||||||
| #ifndef GPS_L1_CA_LS_PVT_H_ | #ifndef GPS_L1_CA_LS_PVT_H_ | ||||||
| #define GPS_L1_CA_LS_PVT_H_ | #define GPS_L1_CA_LS_PVT_H_ | ||||||
| 
 | 
 | ||||||
|  | #include <fstream> | ||||||
| #include <string> | #include <string> | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <sstream> | #include <sstream> | ||||||
| @@ -67,14 +68,30 @@ public: | |||||||
|     double d_latitude_d; |     double d_latitude_d; | ||||||
|     double d_longitude_d; |     double d_longitude_d; | ||||||
|     double d_height_m; |     double d_height_m; | ||||||
|  |     //averaging
 | ||||||
|  |     std::deque<double> d_hist_latitude_d; | ||||||
|  |     std::deque<double> d_hist_longitude_d; | ||||||
|  |     std::deque<double> d_hist_height_m; | ||||||
|  |     int d_averaging_depth; | ||||||
|  | 
 | ||||||
|  |     double d_avg_latitude_d; | ||||||
|  |     double d_avg_longitude_d; | ||||||
|  |     double d_avg_height_m; | ||||||
|  | 
 | ||||||
|     double d_x_m; |     double d_x_m; | ||||||
|     double d_y_m; |     double d_y_m; | ||||||
|     double d_z_m; |     double d_z_m; | ||||||
| 
 | 
 | ||||||
|     gps_l1_ca_ls_pvt(int nchannels); |     bool d_flag_dump_enabled; | ||||||
|  |     std::string d_dump_filename; | ||||||
|  |     std::ofstream d_dump_file; | ||||||
|  | 
 | ||||||
|  |     void set_averaging_depth(int depth); | ||||||
|  | 
 | ||||||
|  |     gps_l1_ca_ls_pvt(int nchannels,std::string dump_filename, bool flag_dump_to_file); | ||||||
|     ~gps_l1_ca_ls_pvt(); |     ~gps_l1_ca_ls_pvt(); | ||||||
| 
 | 
 | ||||||
|     void get_PVT(std::map<int,float> pseudoranges,double GPS_current_time); |     bool get_PVT(std::map<int,gnss_pseudorange> pseudoranges,double GPS_current_time,bool flag_averaging); | ||||||
|     void cart2geo(double X, double Y, double Z, int elipsoid_selection); |     void cart2geo(double X, double Y, double Z, int elipsoid_selection); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @@ -2,3 +2,4 @@ project : build-dir ../../../../build ; | |||||||
| 
 | 
 | ||||||
| obj rinex_2_1_printer : rinex_2_1_printer.cc ; | obj rinex_2_1_printer : rinex_2_1_printer.cc ; | ||||||
| obj gps_l1_ca_ls_pvt : gps_l1_ca_ls_pvt.cc ; | obj gps_l1_ca_ls_pvt : gps_l1_ca_ls_pvt.cc ; | ||||||
|  | obj kml_printer : kml_printer.cc ; | ||||||
							
								
								
									
										126
									
								
								src/algorithms/PVT/libs/kml_printer.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								src/algorithms/PVT/libs/kml_printer.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | |||||||
|  | /*! | ||||||
|  |  * \file kml_printer.cc | ||||||
|  |  * \brief Prints PVT information to a GoogleEarth kml file | ||||||
|  |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "kml_printer.h" | ||||||
|  | #include <glog/log_severity.h> | ||||||
|  | #include <glog/logging.h> | ||||||
|  |  | ||||||
|  | #include <time.h> | ||||||
|  |  | ||||||
|  | bool kml_printer::set_headers(std::string filename) | ||||||
|  | { | ||||||
|  | 	  time_t rawtime; | ||||||
|  | 	  struct tm * timeinfo; | ||||||
|  |  | ||||||
|  | 	  time ( &rawtime ); | ||||||
|  | 	  timeinfo = localtime ( &rawtime ); | ||||||
|  |  | ||||||
|  |         kml_file.open(filename.c_str()); | ||||||
|  |         if (kml_file.is_open()) | ||||||
|  |         { | ||||||
|  |         	DLOG(INFO)<<"KML printer writting on "<<filename.c_str(); | ||||||
|  |         	kml_file<<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" | ||||||
|  |         			<<"<kml xmlns=\"http://www.opengis.net/kml/2.2\">\r\n" | ||||||
|  |         			<<"	<Document>\r\n" | ||||||
|  |         			<<"	<name>GNSS Track</name>\r\n" | ||||||
|  |         			<<"	<description>GNSS-SDR Receiver position log file created at "<<asctime (timeinfo) | ||||||
|  |         			<<"	</description>\r\n" | ||||||
|  |         			<<"<Style id=\"yellowLineGreenPoly\">\r\n" | ||||||
|  |         			<<" <LineStyle>\r\n" | ||||||
|  |         			<<" 	<color>7f00ffff</color>\r\n" | ||||||
|  |         			<<"		<width>1</width>\r\n" | ||||||
|  |         			<<"	</LineStyle>\r\n" | ||||||
|  |         			<<"<PolyStyle>\r\n" | ||||||
|  |         			<<"	<color>7f00ff00</color>\r\n" | ||||||
|  |         			<<"</PolyStyle>\r\n" | ||||||
|  |         			<<"</Style>\r\n" | ||||||
|  |         			<<"<Placemark>\r\n" | ||||||
|  |         			<<"<name>GNSS-SDR PVT</name>\r\n" | ||||||
|  |         			<<"<description>GNSS-SDR position log</description>\r\n" | ||||||
|  |         			<<"<styleUrl>#yellowLineGreenPoly</styleUrl>\r\n" | ||||||
|  |         			<<"<LineString>\r\n" | ||||||
|  |         			<<"<extrude>0</extrude>\r\n" | ||||||
|  |         			<<"<tessellate>1</tessellate>\r\n" | ||||||
|  |         			<<"<altitudeMode>absolute</altitudeMode>\r\n" | ||||||
|  |         			<<"<coordinates>\r\n"; | ||||||
|  |         	return true; | ||||||
|  |         }else{ | ||||||
|  |         	return false; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool kml_printer::print_position(gps_l1_ca_ls_pvt* position,bool print_average_values) | ||||||
|  | { | ||||||
|  | 	double latitude; | ||||||
|  | 	double longitude; | ||||||
|  | 	double height; | ||||||
|  | 	if (print_average_values==false) | ||||||
|  | 	{ | ||||||
|  | 		latitude=position->d_latitude_d; | ||||||
|  | 		longitude=position->d_longitude_d; | ||||||
|  | 		height=position->d_height_m; | ||||||
|  | 	}else{ | ||||||
|  | 		latitude=position->d_avg_latitude_d; | ||||||
|  | 		longitude=position->d_avg_longitude_d; | ||||||
|  | 		height=position->d_avg_height_m; | ||||||
|  | 	} | ||||||
|  |     if (kml_file.is_open()) | ||||||
|  |     { | ||||||
|  |     	kml_file<<longitude<<","<<latitude<<","<<height<<"\r\n"; | ||||||
|  |     	return true; | ||||||
|  |     }else | ||||||
|  |     { | ||||||
|  |     	return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | bool kml_printer::close_file() | ||||||
|  | { | ||||||
|  |     if (kml_file.is_open()) | ||||||
|  |     { | ||||||
|  |     	kml_file<<"</coordinates>\r\n" | ||||||
|  |         <<"</LineString>\r\n" | ||||||
|  |         <<"</Placemark>\r\n" | ||||||
|  |         <<"</Document>\r\n" | ||||||
|  |         <<"</kml>"; | ||||||
|  |     	kml_file.close(); | ||||||
|  |     	return true; | ||||||
|  |     }else{ | ||||||
|  |     	return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | kml_printer::kml_printer () | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | kml_printer::~kml_printer () | ||||||
|  | { | ||||||
|  | } | ||||||
							
								
								
									
										59
									
								
								src/algorithms/PVT/libs/kml_printer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/algorithms/PVT/libs/kml_printer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | /*! | ||||||
|  |  * \file kml_printer.h | ||||||
|  |  * \brief Prints PVT information to a GoogleEarth kml file | ||||||
|  |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifndef KML_PRINTER_H_ | ||||||
|  | #define	KML_PRINTER_H_ | ||||||
|  |  | ||||||
|  | #include <iostream> | ||||||
|  | #include <fstream> | ||||||
|  |  | ||||||
|  | #include "gps_l1_ca_ls_pvt.h" | ||||||
|  |  | ||||||
|  | class kml_printer | ||||||
|  | { | ||||||
|  | private: | ||||||
|  |  | ||||||
|  | 	std::ofstream kml_file; | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |  | ||||||
|  | 	bool set_headers(std::string filename); | ||||||
|  |  | ||||||
|  | 	bool print_position(gps_l1_ca_ls_pvt* position,bool print_average_values); | ||||||
|  |  | ||||||
|  | 	bool close_file(); | ||||||
|  |  | ||||||
|  | 	kml_printer(); | ||||||
|  | 	~kml_printer(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif | ||||||
| @@ -30,7 +30,7 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "gps_l1_ca_gps_sdr_acquisition.h" | #include "gps_l1_ca_gps_sdr_acquisition.h" | ||||||
|  | #include "GPS_L1_CA.h" | ||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
|  |  | ||||||
| #include <gnuradio/gr_io_signature.h> | #include <gnuradio/gr_io_signature.h> | ||||||
| @@ -63,7 +63,7 @@ GpsL1CaGpsSdrAcquisition::GpsL1CaGpsSdrAcquisition( | |||||||
|     //vector_length_ = configuration->property(role + ".vector_length", 2048); |     //vector_length_ = configuration->property(role + ".vector_length", 2048); | ||||||
|  |  | ||||||
|     satellite_ = 0; |     satellite_ = 0; | ||||||
|     fs_in_ = configuration->property(role + ".fs_in", 2048000); |     fs_in_ = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||||
|     if_ = configuration->property(role + ".ifreq", 0); |     if_ = configuration->property(role + ".ifreq", 0); | ||||||
|     dump_ = configuration->property(role + ".dump", false); |     dump_ = configuration->property(role + ".dump", false); | ||||||
|     doppler_max_ = 0; |     doppler_max_ = 0; | ||||||
| @@ -74,9 +74,7 @@ GpsL1CaGpsSdrAcquisition::GpsL1CaGpsSdrAcquisition( | |||||||
|     //vector_length_=ceil((float)fs_in_*((float)acquisition_ms_/1000)); |     //vector_length_=ceil((float)fs_in_*((float)acquisition_ms_/1000)); | ||||||
|  |  | ||||||
|     //--- Find number of samples per spreading code ---------------------------- |     //--- Find number of samples per spreading code ---------------------------- | ||||||
|     const int32 _codeFreqBasis = 1023000; //Hz |     vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); | ||||||
|     const int32 _codeLength = 1023; |  | ||||||
|     vector_length_ = round(fs_in_ / (_codeFreqBasis / _codeLength)); |  | ||||||
|  |  | ||||||
|     printf("vector_length_ %i\n\r", vector_length_); |     printf("vector_length_ %i\n\r", vector_length_); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "gps_l1_ca_pcps_acquisition.h" | #include "gps_l1_ca_pcps_acquisition.h" | ||||||
|  | #include "GPS_L1_CA.h" | ||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <gnuradio/gr_io_signature.h> | #include <gnuradio/gr_io_signature.h> | ||||||
| @@ -63,7 +63,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( | |||||||
|             default_item_type); |             default_item_type); | ||||||
|  |  | ||||||
|     satellite_ = 0; |     satellite_ = 0; | ||||||
|     fs_in_ = configuration->property(role + ".fs_in", 2048000); |     fs_in_ = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||||
|     if_ = configuration->property(role + ".ifreq", 0); |     if_ = configuration->property(role + ".ifreq", 0); | ||||||
|     dump_ = configuration->property(role + ".dump", false); |     dump_ = configuration->property(role + ".dump", false); | ||||||
|     shift_resolution_ = configuration->property(role + ".doppler_max", 15); |     shift_resolution_ = configuration->property(role + ".doppler_max", 15); | ||||||
| @@ -72,12 +72,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( | |||||||
|             default_dump_filename); |             default_dump_filename); | ||||||
|  |  | ||||||
|     //--- Find number of samples per spreading code ---------------------------- |     //--- Find number of samples per spreading code ---------------------------- | ||||||
|     const signed int _codeFreqBasis = 1023000; //Hz |     vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); | ||||||
|     const signed int _codeLength = 1023; |  | ||||||
|     std::cout << fs_in_ << " " << role << std::endl; |  | ||||||
|     vector_length_ = round(fs_in_ / (_codeFreqBasis / _codeLength)); |  | ||||||
|  |  | ||||||
|     printf("vector_length_ %i\n\r", vector_length_); |  | ||||||
|  |  | ||||||
|     if (item_type_.compare("gr_complex") == 0) |     if (item_type_.compare("gr_complex") == 0) | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "gps_l1_ca_tong_pcps_acquisition.h" | #include "gps_l1_ca_tong_pcps_acquisition.h" | ||||||
|  | #include "GPS_L1_CA.h" | ||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
|  |  | ||||||
| #include <gnuradio/gr_io_signature.h> | #include <gnuradio/gr_io_signature.h> | ||||||
| @@ -64,7 +64,7 @@ GpsL1CaTongPcpsAcquisition::GpsL1CaTongPcpsAcquisition( | |||||||
|     std::cout << "item type " << item_type_ << std::endl; |     std::cout << "item type " << item_type_ << std::endl; | ||||||
|  |  | ||||||
|     satellite_ = 0; |     satellite_ = 0; | ||||||
|     fs_in_ = configuration->property(role + ".fs_in", 2048000); |     fs_in_ = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||||
|     if_ = configuration->property(role + ".ifreq", 0); |     if_ = configuration->property(role + ".ifreq", 0); | ||||||
|     dump_ = configuration->property(role + ".dump", false); |     dump_ = configuration->property(role + ".dump", false); | ||||||
|     doppler_max_ = configuration->property(role + ".doppler_max", 10); |     doppler_max_ = configuration->property(role + ".doppler_max", 10); | ||||||
| @@ -73,11 +73,7 @@ GpsL1CaTongPcpsAcquisition::GpsL1CaTongPcpsAcquisition( | |||||||
|             default_dump_filename); |             default_dump_filename); | ||||||
|  |  | ||||||
|     //--- Find number of samples per spreading code ---------------------------- |     //--- Find number of samples per spreading code ---------------------------- | ||||||
|     const signed int _codeFreqBasis = 1023000; //Hz |     vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); | ||||||
|     const signed int _codeLength = 1023; |  | ||||||
|     vector_length_ = round(fs_in_ / (_codeFreqBasis / _codeLength)); |  | ||||||
|  |  | ||||||
|     printf("vector_length_ %i\n\r", vector_length_); |  | ||||||
|  |  | ||||||
|     if (item_type_.compare("gr_complex") == 0) |     if (item_type_.compare("gr_complex") == 0) | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -31,9 +31,6 @@ | |||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #ifdef HAVE_CONFIG_H |  | ||||||
| #include "config.h" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include "gps_l1_ca_gps_sdr_acquisition_cc.h" | #include "gps_l1_ca_gps_sdr_acquisition_cc.h" | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
| @@ -126,15 +123,15 @@ gps_l1_ca_gps_sdr_acquisition_cc::gps_l1_ca_gps_sdr_acquisition_cc( | |||||||
|  |  | ||||||
| gps_l1_ca_gps_sdr_acquisition_cc::~gps_l1_ca_gps_sdr_acquisition_cc() | gps_l1_ca_gps_sdr_acquisition_cc::~gps_l1_ca_gps_sdr_acquisition_cc() | ||||||
| { | { | ||||||
|     delete d_sine_if; |     delete[] d_sine_if; | ||||||
|     delete d_sine_250; |     delete[] d_sine_250; | ||||||
|     delete d_sine_500; |     delete[] d_sine_500; | ||||||
|     delete d_sine_750; |     delete[] d_sine_750; | ||||||
|     delete d_fft_codes; |     delete[] d_fft_codes; | ||||||
|     delete d_fft_if; |     delete[] d_fft_if; | ||||||
|     delete d_fft_250; |     delete[] d_fft_250; | ||||||
|     delete d_fft_500; |     delete[] d_fft_500; | ||||||
|     delete d_fft_750; |     delete[] d_fft_750; | ||||||
|  |  | ||||||
|     if (d_dump) |     if (d_dump) | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -30,10 +30,6 @@ | |||||||
|  * |  * | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| #ifdef HAVE_CONFIG_H |  | ||||||
| #include "config.h" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include "gps_l1_ca_gps_sdr_acquisition_ss.h" | #include "gps_l1_ca_gps_sdr_acquisition_ss.h" | ||||||
|  |  | ||||||
| #include "gps_sdr_simd.h" | #include "gps_sdr_simd.h" | ||||||
| @@ -129,12 +125,12 @@ gps_l1_ca_gps_sdr_acquisition_ss::gps_l1_ca_gps_sdr_acquisition_ss( | |||||||
|  |  | ||||||
| gps_l1_ca_gps_sdr_acquisition_ss::~gps_l1_ca_gps_sdr_acquisition_ss() | gps_l1_ca_gps_sdr_acquisition_ss::~gps_l1_ca_gps_sdr_acquisition_ss() | ||||||
| { | { | ||||||
|     delete d_baseband_signal; |     delete[] d_baseband_signal; | ||||||
|     delete d_baseband_signal_shift; |     delete[] d_baseband_signal_shift; | ||||||
|     delete d_sine_if; |     delete[] d_sine_if; | ||||||
|     delete d_sine_250; |     delete[] d_sine_250; | ||||||
|     delete d_sine_500; |     delete[] d_sine_500; | ||||||
|     delete d_sine_750; |     delete[] d_sine_750; | ||||||
|     delete d_pFFT; |     delete d_pFFT; | ||||||
|     delete d_piFFT; |     delete d_piFFT; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -31,10 +31,6 @@ | |||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #ifdef HAVE_CONFIG_H |  | ||||||
| #include "config.h" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include "gps_l1_ca_pcps_acquisition_cc.h" | #include "gps_l1_ca_pcps_acquisition_cc.h" | ||||||
| #include "gps_sdr_signal_processing.h" | #include "gps_sdr_signal_processing.h" | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
| @@ -117,8 +113,10 @@ gps_l1_ca_pcps_acquisition_cc::gps_l1_ca_pcps_acquisition_cc( | |||||||
|  |  | ||||||
| gps_l1_ca_pcps_acquisition_cc::~gps_l1_ca_pcps_acquisition_cc() | gps_l1_ca_pcps_acquisition_cc::~gps_l1_ca_pcps_acquisition_cc() | ||||||
| { | { | ||||||
|     delete d_sine_if; | 	delete[] d_sine_if; | ||||||
|     delete d_fft_codes; | 	delete[] d_fft_codes; | ||||||
|  | 	delete d_ifft; | ||||||
|  | 	delete d_fft_if; | ||||||
|  |  | ||||||
|     if (d_dump) |     if (d_dump) | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -29,9 +29,6 @@ | |||||||
|  * |  * | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| #ifdef HAVE_CONFIG_H |  | ||||||
| #include "config.h" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include "gps_l1_ca_tong_pcps_acquisition_cc.h" | #include "gps_l1_ca_tong_pcps_acquisition_cc.h" | ||||||
| #include "gps_sdr_signal_processing.h" | #include "gps_sdr_signal_processing.h" | ||||||
| @@ -129,8 +126,11 @@ gps_l1_ca_tong_pcps_acquisition_cc::gps_l1_ca_tong_pcps_acquisition_cc( | |||||||
|  |  | ||||||
| gps_l1_ca_tong_pcps_acquisition_cc::~gps_l1_ca_tong_pcps_acquisition_cc() | gps_l1_ca_tong_pcps_acquisition_cc::~gps_l1_ca_tong_pcps_acquisition_cc() | ||||||
| { | { | ||||||
|     delete d_if_sin; |     delete[] d_if_sin; | ||||||
|     delete d_ca_codes; |     delete[] d_ca_codes; | ||||||
|  |     delete[] d_aux_ca_code; | ||||||
|  |     delete d_fft_if; | ||||||
|  |     delete d_ifft; | ||||||
|  |  | ||||||
|     if (d_dump) |     if (d_dump) | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -77,7 +77,7 @@ Channel::Channel(ConfigurationInterface *configuration, unsigned int channel, | |||||||
|  |  | ||||||
|     repeat_ = configuration->property("Acquisition" + boost::lexical_cast< |     repeat_ = configuration->property("Acquisition" + boost::lexical_cast< | ||||||
|             std::string>(channel_) + ".repeat_satellite", false); |             std::string>(channel_) + ".repeat_satellite", false); | ||||||
|     std::cout << "Channel " << channel_ << " satellite repeat = " << repeat_ |     DLOG(INFO) << "Channel " << channel_ << " satellite repeat = " << repeat_ | ||||||
|             << std::endl; |             << std::endl; | ||||||
|  |  | ||||||
|     acq_->set_channel_queue(&channel_internal_queue_); |     acq_->set_channel_queue(&channel_internal_queue_); | ||||||
|   | |||||||
| @@ -6,4 +6,5 @@ build-project signal_source ; | |||||||
| build-project tracking ; | build-project tracking ; | ||||||
| build-project telemetry_decoder ; | build-project telemetry_decoder ; | ||||||
| build-project observables ; | build-project observables ; | ||||||
|  | build-project PVT ; | ||||||
| build-project output_filter ; | build-project output_filter ; | ||||||
| @@ -333,7 +333,7 @@ int32 run_agc(CPX *_buff, int32 _samps, int32 _bits, int32 _scale) | |||||||
|  |  | ||||||
| 	p = (int16 *)&_buff[0]; | 	p = (int16 *)&_buff[0]; | ||||||
|  |  | ||||||
| 	val = (1 << _scale - 1); | 	val = (1 << (_scale - 1)); | ||||||
| 	max = 1 << _bits; | 	max = 1 << _bits; | ||||||
| 	num = 0; | 	num = 0; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -497,7 +497,7 @@ void sse_cmul(CPX *A, CPX *B, int32 cnt) | |||||||
| 	int32 cnt1; | 	int32 cnt1; | ||||||
| 	int32 cnt2; | 	int32 cnt2; | ||||||
|  |  | ||||||
| 	volatile int32 M[4] = {0xffff0001, 0x00010001, 0xffff0001, 0x00010001}; //{1,-1,1,1,1,-1,1,1}; | 	//volatile int32 M[4] = {0xffff0001, 0x00010001, 0xffff0001, 0x00010001}; //{1,-1,1,1,1,-1,1,1}; | ||||||
|  |  | ||||||
| 	cnt1 = cnt/4; | 	cnt1 = cnt/4; | ||||||
| 	cnt2 = cnt-4*cnt1; | 	cnt2 = cnt-4*cnt1; | ||||||
| @@ -571,7 +571,7 @@ void sse_cmuls(CPX *A, CPX *B, int32 cnt, int32 shift) | |||||||
| 	int32 cnt2; | 	int32 cnt2; | ||||||
| 	int32 round; | 	int32 round; | ||||||
|  |  | ||||||
| 	volatile int32 M[4] = {0xffff0001, 0x00010001, 0xffff0001, 0x00010001}; //{1,-1,1,1,1,-1,1,1}; | 	//volatile int32 M[4] = {0xffff0001, 0x00010001, 0xffff0001, 0x00010001}; //{1,-1,1,1,1,-1,1,1}; | ||||||
|  |  | ||||||
| 	cnt1 = cnt/4; | 	cnt1 = cnt/4; | ||||||
| 	cnt2 = cnt-4*cnt1; | 	cnt2 = cnt-4*cnt1; | ||||||
| @@ -652,7 +652,7 @@ void sse_cmulsc(CPX *A, CPX *B, CPX *C, int32 cnt, int32 shift) | |||||||
| 	int32 cnt2; | 	int32 cnt2; | ||||||
| 	int32 round; | 	int32 round; | ||||||
|  |  | ||||||
| 	volatile int32 M[4] = {0xffff0001, 0x00010001, 0xffff0001, 0x00010001}; //{1,-1,1,1,1,-1,1,1}; | 	//volatile int32 M[4] = {0xffff0001, 0x00010001, 0xffff0001, 0x00010001}; //{1,-1,1,1,1,-1,1,1}; | ||||||
|  |  | ||||||
| 	cnt1 = cnt/4; | 	cnt1 = cnt/4; | ||||||
| 	cnt2 = cnt-4*cnt1; | 	cnt2 = cnt-4*cnt1; | ||||||
|   | |||||||
| @@ -290,7 +290,7 @@ void x86_float_max(float* _A, unsigned int* _index, float* _magt, unsigned int _ | |||||||
|  |  | ||||||
| 	mag = index = 0; | 	mag = index = 0; | ||||||
|  |  | ||||||
| 	for(int i=0; i<_cnt; i++) { | 	for(unsigned int i=0; i<_cnt; i++) { | ||||||
| 		if(_A[i] > mag) { | 		if(_A[i] > mag) { | ||||||
| 			index = i; | 			index = i; | ||||||
| 			mag = _A[i]; | 			mag = _A[i]; | ||||||
|   | |||||||
| @@ -60,15 +60,21 @@ GpsL1CaObservables::GpsL1CaObservables(ConfigurationInterface* configuration, | |||||||
|         queue_(queue) |         queue_(queue) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | 	int output_rate_ms; | ||||||
|  | 	output_rate_ms=configuration->property(role + ".output_rate_ms", 500); | ||||||
|  |  | ||||||
|     std::string default_dump_filename = "./observables.dat"; |     std::string default_dump_filename = "./observables.dat"; | ||||||
|  |  | ||||||
|     DLOG(INFO) << "role " << role; |     DLOG(INFO) << "role " << role; | ||||||
|  |  | ||||||
|  |     bool flag_averaging; | ||||||
|  |     flag_averaging=configuration->property(role + ".flag_averaging", false); | ||||||
|  |  | ||||||
|     dump_ = configuration->property(role + ".dump", false); |     dump_ = configuration->property(role + ".dump", false); | ||||||
|     dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); |     dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); | ||||||
| 	fs_in_ = configuration->property(role + ".fs_in", 0); |     fs_in_ = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||||
|  |  | ||||||
| 	observables_ = gps_l1_ca_make_observables_cc(in_streams_, queue_, dump_); | 	observables_ = gps_l1_ca_make_observables_cc(in_streams_, queue_, dump_,dump_filename_,output_rate_ms,flag_averaging); | ||||||
| 	observables_->set_fs_in(fs_in_); | 	observables_->set_fs_in(fs_in_); | ||||||
|  |  | ||||||
|     DLOG(INFO) << "pseudorange(" << observables_->unique_id() << ")"; |     DLOG(INFO) << "pseudorange(" << observables_->unique_id() << ")"; | ||||||
|   | |||||||
| @@ -1,17 +1,32 @@ | |||||||
|  | /*! | ||||||
| /** |  * \file gps_l1_ca_observables_cc.cc | ||||||
|  * Copyright notice |  * \brief Pseudorange computation module for GPS L1 C/A | ||||||
|  |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Author: Javier Arribas, 2011. jarribas(at)cttc.es |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef HAVE_CONFIG_H |  | ||||||
| #include "config.h" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <sstream> | #include <sstream> | ||||||
| #include <vector> | #include <vector> | ||||||
| @@ -37,165 +52,236 @@ using namespace std; | |||||||
|  |  | ||||||
|  |  | ||||||
| gps_l1_ca_observables_cc_sptr | gps_l1_ca_observables_cc_sptr | ||||||
| gps_l1_ca_make_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump) { | gps_l1_ca_make_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging) { | ||||||
|  |  | ||||||
|   return gps_l1_ca_observables_cc_sptr(new gps_l1_ca_observables_cc(nchannels, queue, dump)); |   return gps_l1_ca_observables_cc_sptr(new gps_l1_ca_observables_cc(nchannels, queue, dump, dump_filename, output_rate_ms, flag_averaging)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| gps_l1_ca_observables_cc::gps_l1_ca_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump) : | gps_l1_ca_observables_cc::gps_l1_ca_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging) : | ||||||
| 		        gr_block ("gps_l1_ca_observables_cc", gr_make_io_signature (nchannels, nchannels,  sizeof(gnss_synchro)), | 		        gr_block ("gps_l1_ca_observables_cc", gr_make_io_signature (nchannels, nchannels,  sizeof(gnss_synchro)), | ||||||
| 		            gr_make_io_signature(1, 1, sizeof(gr_complex))) { | 		            gr_make_io_signature(nchannels, nchannels, sizeof(gnss_pseudorange))) { | ||||||
|   //TODO: change output channels to have Pseudorange GNURadio signature: nchannels input (float), nchannels output (float) |  | ||||||
|   // initialize internal vars |   // initialize internal vars | ||||||
|   d_queue = queue; |   d_queue = queue; | ||||||
|   d_dump = dump; |   d_dump = dump; | ||||||
|   d_nchannels = nchannels; |   d_nchannels = nchannels; | ||||||
|   d_rinex_printer.set_headers("GNSS-SDR"); //TODO: read filename from config |   d_output_rate_ms=output_rate_ms; | ||||||
|   d_ls_pvt=new gps_l1_ca_ls_pvt(nchannels); |   d_history_prn_delay_ms= new std::deque<double>[d_nchannels]; | ||||||
|   d_ephemeris_clock_s=0.0; |   d_dump_filename=dump_filename; | ||||||
|   if (d_dump==true) |   d_flag_averaging=flag_averaging; | ||||||
|   { |  | ||||||
|       std::stringstream d_dump_filename_str;//create a stringstream to form the dump filename | 	// ############# ENABLE DATA FILE LOG ################# | ||||||
|       d_dump_filename_str<<"./data/obs.dat"; //TODO: get filename and path from config in the adapter | 	if (d_dump==true) | ||||||
|       d_dump_filename=d_dump_filename_str.str(); | 	{ | ||||||
|       d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); | 		if (d_dump_file.is_open()==false) | ||||||
|   } | 		{ | ||||||
|  | 			try { | ||||||
|  | 				d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit ); | ||||||
|  | 				d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); | ||||||
|  | 				std::cout<<"Observables dump enabled Log file: "<<d_dump_filename.c_str()<<std::endl; | ||||||
|  | 			} | ||||||
|  | 			catch (std::ifstream::failure e) { | ||||||
|  | 				std::cout << "Exception opening observables dump file "<<e.what()<<"\r\n"; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| gps_l1_ca_observables_cc::~gps_l1_ca_observables_cc() { | gps_l1_ca_observables_cc::~gps_l1_ca_observables_cc() { | ||||||
|  | 	d_dump_file.close(); | ||||||
|     delete d_ls_pvt; | 	delete[] d_history_prn_delay_ms; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool pairCompare_min( pair<int,gnss_synchro> a, pair<int,gnss_synchro> b) | bool pairCompare_gnss_synchro( pair<int,gnss_synchro> a, pair<int,gnss_synchro> b) | ||||||
| { | { | ||||||
|   return (a.second.preamble_delay_ms+a.second.prn_delay_ms) < (b.second.preamble_delay_ms+b.second.prn_delay_ms); |   return (a.second.preamble_delay_ms) < (b.second.preamble_delay_ms); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool pairCompare_max( pair<int,gnss_synchro> a, pair<int,gnss_synchro> b) | bool pairCompare_double( pair<int,double> a, pair<int,double> b) | ||||||
| { | { | ||||||
|     return (a.second.preamble_delay_ms+a.second.prn_delay_ms) > (b.second.preamble_delay_ms+b.second.prn_delay_ms); |   return (a.second) < (b.second); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void clearQueue( std::deque<double> &q ) | ||||||
|  | { | ||||||
|  |    std::deque<double> empty; | ||||||
|  |    std::swap( q, empty ); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| int gps_l1_ca_observables_cc::general_work (int noutput_items, gr_vector_int &ninput_items, | int gps_l1_ca_observables_cc::general_work (int noutput_items, gr_vector_int &ninput_items, | ||||||
|     gr_vector_const_void_star &input_items,	gr_vector_void_star &output_items) { |     gr_vector_const_void_star &input_items,	gr_vector_void_star &output_items) { | ||||||
|  |  | ||||||
|   gnss_synchro **in = (gnss_synchro **)  &input_items[0]; //Get the input samples pointer |   gnss_synchro **in = (gnss_synchro **)  &input_items[0]; //Get the input pointer | ||||||
|  |   gnss_pseudorange **out = (gnss_pseudorange **)  &output_items[0]; //Get the output pointer | ||||||
|  |  | ||||||
|   // CONSTANTS TODO: place in a file |   gnss_pseudorange current_gnss_pseudorange; | ||||||
|   const float code_length_s=0.001; //1 ms |  | ||||||
|   const float C_m_ms= GPS_C_m_s/1000.0;    // The speed of light, [m/ms] |  | ||||||
|  |  | ||||||
|   const float nav_sol_period_ms=1000; |  | ||||||
|   //--- Find number of samples per spreading code ---------------------------- |  | ||||||
|   const signed int codeFreqBasis=1023000; //Hz |  | ||||||
|   const signed int codeLength=1023; |  | ||||||
|   const unsigned int samples_per_code = round(d_fs_in/ (codeFreqBasis / codeLength)); |  | ||||||
|  |  | ||||||
|   map<int,gnss_synchro> gps_words; |   map<int,gnss_synchro> gps_words; | ||||||
|   map<int,gnss_synchro>::iterator gps_words_iter; |   map<int,gnss_synchro>::iterator gps_words_iter; | ||||||
|  |  | ||||||
|   map<int,float> pseudoranges; |   map<int,double>::iterator current_prn_timestamps_ms_iter; | ||||||
|   map<int,float>::iterator pseudoranges_iter; |   map<int,double> current_prn_timestamps_ms; | ||||||
|   map<int,float> pseudoranges_dump; |  | ||||||
|  |  | ||||||
|   float min_preamble_delay_ms; |   double min_preamble_delay_ms; | ||||||
|   float max_preamble_delay_ms; |   double max_preamble_delay_ms; | ||||||
|   bool  flag_valid_pseudoranges=false; |  | ||||||
|  |  | ||||||
|   float pseudoranges_timestamp_ms; |   double pseudoranges_timestamp_ms; | ||||||
|   float traveltime_ms; |   double traveltime_ms; | ||||||
|   float pseudorange_m; |   double pseudorange_m; | ||||||
|  |   int history_shift=0; | ||||||
|  |   double delta_timestamp_ms; | ||||||
|  |   double min_delta_timestamp_ms; | ||||||
|  |   double actual_min_prn_delay_ms; | ||||||
|  |   double current_prn_delay_ms; | ||||||
|  |  | ||||||
|   int pseudoranges_reference_sat_ID=0; |   int pseudoranges_reference_sat_ID=0; | ||||||
|  |   unsigned int pseudoranges_reference_sat_channel_ID=0; | ||||||
|  |  | ||||||
|  |   d_sample_counter++; //count for the processed samples | ||||||
|  |  | ||||||
|  |   bool flag_history_ok=true; //flag to indicate that all the queues have filled their timestamp history | ||||||
|  |   /*! | ||||||
|  |    * 1. Read the GNSS SYNCHRO objects from available channels to obtain the preamble timestamp, current PRN start time and accumulated carrier phase | ||||||
|  |    */ | ||||||
|   for (unsigned int i=0; i<d_nchannels ; i++) |   for (unsigned int i=0; i<d_nchannels ; i++) | ||||||
|     { |     { | ||||||
|     if (in[i][0].valid_word) //if this channel have valid word |     if (in[i][0].valid_word) //if this channel have valid word | ||||||
|       { |       { | ||||||
|       gps_words.insert(pair<int,gnss_synchro>(in[i][0].channel_ID,in[i][0])); //record the word structure in a map for pseudoranges |       gps_words.insert(pair<int,gnss_synchro>(in[i][0].channel_ID,in[i][0])); //record the word structure in a map for pseudoranges | ||||||
|       } |       // RECORD PRN start timestamps history | ||||||
|     } |       if (d_history_prn_delay_ms[i].size()<MAX_TOA_DELAY_MS) | ||||||
|  |  | ||||||
|   if(gps_words.size()>0) |  | ||||||
|     { |  | ||||||
|  |  | ||||||
|       // find the minimum index (nearest satellite, will be the reference) |  | ||||||
|       gps_words_iter=min_element(gps_words.begin(),gps_words.end(),pairCompare_min); |  | ||||||
|       min_preamble_delay_ms=gps_words_iter->second.preamble_delay_ms+gps_words_iter->second.prn_delay_ms; //[ms] |  | ||||||
|       pseudoranges_timestamp_ms=min_preamble_delay_ms; //save the shortest pseudorange timestamp to compute the RINEX timestamp |  | ||||||
|       pseudoranges_reference_sat_ID=gps_words_iter->second.satellite_PRN; |  | ||||||
|       gps_words_iter=max_element(gps_words.begin(),gps_words.end(),pairCompare_max); |  | ||||||
|       max_preamble_delay_ms=gps_words_iter->second.preamble_delay_ms; //[ms] |  | ||||||
|  |  | ||||||
|       if ((max_preamble_delay_ms-min_preamble_delay_ms)<70) flag_valid_pseudoranges=true; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|       //compute the pseudoranges |  | ||||||
|       for(gps_words_iter = gps_words.begin(); gps_words_iter != gps_words.end(); gps_words_iter++) |  | ||||||
|         { |  | ||||||
|         std::cout<<"prn_delay="<<gps_words_iter->second.prn_delay_ms<<std::endl; |  | ||||||
|         traveltime_ms=gps_words_iter->second.preamble_delay_ms+gps_words_iter->second.prn_delay_ms-min_preamble_delay_ms+GPS_STARTOFFSET_ms; //[ms] |  | ||||||
|         pseudorange_m=traveltime_ms*C_m_ms; // [m] |  | ||||||
|         pseudoranges.insert(pair<int,float>(gps_words_iter->second.satellite_PRN,pseudorange_m)); //record the preamble index in a map |  | ||||||
|         if (d_dump==true) |  | ||||||
|         { |  | ||||||
|             pseudoranges_dump.insert(pair<int,float>(gps_words_iter->second.channel_ID,pseudorange_m)); |  | ||||||
|         } |  | ||||||
|         } |  | ||||||
|     // write the pseudoranges to RINEX OBS file |  | ||||||
|     // 1- need a valid clock |  | ||||||
|     if (flag_valid_pseudoranges==true and d_last_nav_msg.d_satellite_PRN>0) |  | ||||||
|       { |       { | ||||||
|         //d_rinex_printer.LogRinex2Obs(d_last_nav_msg,d_ephemeris_clock_s+((double)pseudoranges_timestamp_ms-d_ephemeris_timestamp_ms)/1000.0,pseudoranges); |     	  d_history_prn_delay_ms[i].push_front(in[i][0].prn_delay_ms); | ||||||
|         // compute on the fly PVT solution |     	  flag_history_ok=false; // at least one channel need more samples | ||||||
|         d_ls_pvt->get_PVT(pseudoranges,d_ephemeris_clock_s+((double)pseudoranges_timestamp_ms-d_ephemeris_timestamp_ms)/1000.0); |       }else{ | ||||||
|  |     	  //clearQueue(d_history_prn_delay_ms[i]); //clear the queue as the preamble arrives | ||||||
|  |     	  d_history_prn_delay_ms[i].pop_back(); | ||||||
|  |     	  d_history_prn_delay_ms[i].push_front(in[i][0].prn_delay_ms); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   //debug |  | ||||||
|   cout << setprecision(16); |  | ||||||
|   for(pseudoranges_iter = pseudoranges.begin(); |  | ||||||
|       pseudoranges_iter != pseudoranges.end(); |  | ||||||
|       pseudoranges_iter++) |  | ||||||
|     { |  | ||||||
|     cout<<"Pseudoranges =("<<pseudoranges_iter->first<<","<<pseudoranges_iter->second<<")"<<endl; |  | ||||||
|     } |  | ||||||
|   gps_navigation_message nav_msg; |  | ||||||
|   if (d_nav_queue->try_pop(nav_msg)==true) |  | ||||||
|     { |  | ||||||
|     cout<<"New ephemeris record has arrived from SAT ID "<<nav_msg.d_satellite_PRN<<endl; |  | ||||||
|     d_last_nav_msg=nav_msg; |  | ||||||
|     d_ls_pvt->d_ephemeris[nav_msg.d_channel_ID]=nav_msg; |  | ||||||
|     // **** update pseudoranges clock **** |  | ||||||
|     if (nav_msg.d_satellite_PRN==pseudoranges_reference_sat_ID) |  | ||||||
|     { |  | ||||||
|         d_ephemeris_clock_s=d_last_nav_msg.d_TOW; |  | ||||||
|         d_ephemeris_timestamp_ms=d_last_nav_msg.d_subframe1_timestamp_ms; |  | ||||||
|     } |  | ||||||
|     // **** write ephemeris to RINES NAV file |  | ||||||
|     //d_rinex_printer.LogRinex2Nav(nav_msg); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   if (d_dump==true) |   /*! | ||||||
|  |    * 1.2 Assume no satellites in tracking | ||||||
|  |    */ | ||||||
|  |   for (unsigned int i=0; i<d_nchannels ; i++) | ||||||
|   { |   { | ||||||
|       float tmp_float=0.0; | 	  current_gnss_pseudorange.valid=false; | ||||||
|       for (int i=0;i<d_nchannels;i++) | 	  current_gnss_pseudorange.SV_ID=0; | ||||||
|       { | 	  current_gnss_pseudorange.pseudorange_m=0; | ||||||
|         pseudoranges_iter=pseudoranges_dump.find(i); | 	  current_gnss_pseudorange.timestamp_ms=0; | ||||||
|         if (pseudoranges_iter!=pseudoranges_dump.end()) |       *out[i]=current_gnss_pseudorange; | ||||||
|         { |  | ||||||
|             d_dump_file.write((char*)&pseudoranges_iter->second, sizeof(float)); |  | ||||||
|         }else{ |  | ||||||
|             d_dump_file.write((char*)&tmp_float, sizeof(float)); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|   } |   } | ||||||
|  |   /*! | ||||||
|  |    * 2. Compute RAW pseudorranges: Use only the valid channels (channels that are tracking a satellite) | ||||||
|  |    */ | ||||||
|  |   if(gps_words.size()>0 and flag_history_ok==true) | ||||||
|  |     { | ||||||
|  |       /*! | ||||||
|  |        *  2.1 find the minimum preamble timestamp (nearest satellite, will be the reference) | ||||||
|  |        */ | ||||||
|  | 	    // The nearest satellite, first preamble to arrive | ||||||
|  | 		gps_words_iter=min_element(gps_words.begin(),gps_words.end(),pairCompare_gnss_synchro); | ||||||
|  | 		min_preamble_delay_ms=gps_words_iter->second.preamble_delay_ms; //[ms] | ||||||
|  |  | ||||||
|  | 		pseudoranges_reference_sat_ID=gps_words_iter->second.satellite_PRN; // it is the reference! | ||||||
|  | 		pseudoranges_reference_sat_channel_ID=gps_words_iter->second.channel_ID; | ||||||
|  |  | ||||||
|  | 		// The farthest satellite, last preamble to arrive | ||||||
|  | 		gps_words_iter=max_element(gps_words.begin(),gps_words.end(),pairCompare_gnss_synchro); | ||||||
|  | 		max_preamble_delay_ms=gps_words_iter->second.preamble_delay_ms; | ||||||
|  | 		min_delta_timestamp_ms=gps_words_iter->second.prn_delay_ms-max_preamble_delay_ms; //[ms] | ||||||
|  |  | ||||||
|  | 		// check if this is a valid set of observations | ||||||
|  | 		if ((max_preamble_delay_ms-min_preamble_delay_ms)<MAX_TOA_DELAY_MS) | ||||||
|  | 		{ | ||||||
|  | 		  // Now we have to determine were we are in time, compared with the last preamble! -> we select the corresponding history | ||||||
|  | 		  /*! | ||||||
|  | 		   * \todo Explain this better! | ||||||
|  | 		   */ | ||||||
|  | 		  //bool flag_preamble_navigation_now=true; | ||||||
|  | 		  // find again the minimum CURRENT minimum preamble time, taking into account the preamble timeshift | ||||||
|  | 	      for(gps_words_iter = gps_words.begin(); gps_words_iter != gps_words.end(); gps_words_iter++) | ||||||
|  | 				{ | ||||||
|  | 				  delta_timestamp_ms=(gps_words_iter->second.prn_delay_ms-gps_words_iter->second.preamble_delay_ms)-min_delta_timestamp_ms; | ||||||
|  | 				  history_shift=round(delta_timestamp_ms); | ||||||
|  | 				  //std::cout<<"history_shift="<<history_shift<<"\r\n"; | ||||||
|  | 				  current_prn_timestamps_ms.insert(pair<int,double>(gps_words_iter->second.channel_ID,d_history_prn_delay_ms[gps_words_iter->second.channel_ID][history_shift])); | ||||||
|  | 				  // debug: preamble position test | ||||||
|  | 				  //if ((d_history_prn_delay_ms[gps_words_iter->second.channel_ID][history_shift]-gps_words_iter->second.preamble_delay_ms)<0.1) | ||||||
|  | 				  //{std::cout<<"ch "<<gps_words_iter->second.channel_ID<<" current_prn_time-last_preamble_prn_time="<< | ||||||
|  | 					//  d_history_prn_delay_ms[gps_words_iter->second.channel_ID][history_shift]-gps_words_iter->second.preamble_delay_ms<<"\r\n"; | ||||||
|  | 				  //}else{ | ||||||
|  | 					//  flag_preamble_navigation_now=false; | ||||||
|  | 				  //} | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 	      //if (flag_preamble_navigation_now==true) | ||||||
|  | 	      //{ | ||||||
|  | 	      	  //std::cout<<"PREAMBLE NAVIGATION NOW!\r\n"; | ||||||
|  | 	    	  //d_sample_counter=0; | ||||||
|  |  | ||||||
|  | 	      //} | ||||||
|  | 	      current_prn_timestamps_ms_iter=min_element(current_prn_timestamps_ms.begin(),current_prn_timestamps_ms.end(),pairCompare_double); | ||||||
|  |  | ||||||
|  | 		  actual_min_prn_delay_ms=current_prn_timestamps_ms_iter->second; | ||||||
|  |  | ||||||
|  | 		  pseudoranges_timestamp_ms=actual_min_prn_delay_ms; //save the shortest pseudorange timestamp to compute the current GNSS timestamp | ||||||
|  | 		  /*! | ||||||
|  | 		   * 2.2 compute the pseudoranges | ||||||
|  | 		   */ | ||||||
|  |  | ||||||
|  | 		  for(gps_words_iter = gps_words.begin(); gps_words_iter != gps_words.end(); gps_words_iter++) | ||||||
|  | 			{ | ||||||
|  | 			// #### compute the pseudorrange for this satellite ### | ||||||
|  |  | ||||||
|  | 		    current_prn_delay_ms=current_prn_timestamps_ms.at(gps_words_iter->second.channel_ID); | ||||||
|  | 			traveltime_ms=current_prn_delay_ms-actual_min_prn_delay_ms+GPS_STARTOFFSET_ms; //[ms] | ||||||
|  | 			//std::cout<<"delta_time_ms="<<current_prn_delay_ms-actual_min_prn_delay_ms<<"\r\n"; | ||||||
|  | 			pseudorange_m=traveltime_ms*GPS_C_m_ms; // [m] | ||||||
|  |  | ||||||
|  | 			// update the pseudorange object | ||||||
|  | 			current_gnss_pseudorange.pseudorange_m=pseudorange_m; | ||||||
|  | 			current_gnss_pseudorange.timestamp_ms=pseudoranges_timestamp_ms; | ||||||
|  | 			current_gnss_pseudorange.SV_ID=gps_words_iter->second.satellite_PRN; | ||||||
|  | 			current_gnss_pseudorange.valid=true; | ||||||
|  | 			// #### write the pseudorrange block output for this satellite ### | ||||||
|  | 			*out[gps_words_iter->second.channel_ID]=current_gnss_pseudorange; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | 	if(d_dump==true) { | ||||||
|  | 		// MULTIPLEXED FILE RECORDING - Record results to file | ||||||
|  |     	try { | ||||||
|  |     	double tmp_double; | ||||||
|  |     	  for (unsigned int i=0; i<d_nchannels ; i++) | ||||||
|  |     	    { | ||||||
|  |     		  tmp_double=in[i][0].preamble_delay_ms; | ||||||
|  |     		  d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  |     		  tmp_double=in[i][0].prn_delay_ms; | ||||||
|  |     		  d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  |     		  tmp_double=out[i][0].pseudorange_m; | ||||||
|  |     		  d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  |     		  tmp_double=out[i][0].timestamp_ms; | ||||||
|  |     		  d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  |     		  tmp_double=out[i][0].SV_ID; | ||||||
|  |     		  d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  |     	    } | ||||||
|  |     	 } | ||||||
|  | 		  catch (std::ifstream::failure e) { | ||||||
|  | 			std::cout << "Exception writing observables dump file "<<e.what()<<"\r\n"; | ||||||
|  | 		  } | ||||||
|  | 	} | ||||||
|   consume_each(1); //one by one |   consume_each(1); //one by one | ||||||
|   return 0; |   if ((d_sample_counter%d_output_rate_ms)==0) | ||||||
|  |     { | ||||||
|  | 	  return 1; //Output the observables | ||||||
|  |     }else{ | ||||||
|  |     	return 0;//hold on | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,11 +1,32 @@ | |||||||
|  | /*! | ||||||
| /** |  * \file gps_l1_ca_observables_cc.h | ||||||
|  * Copyright notice |  * \brief Pseudorange computation module for GPS L1 C/A | ||||||
|  |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Author: Javier Arribas, 2011. jarribas(at)cttc.es |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifndef GPS_L1_CA_OBSERVABLES_CC_H | #ifndef GPS_L1_CA_OBSERVABLES_CC_H | ||||||
| #define	GPS_L1_CA_OBSERVABLES_CC_H | #define	GPS_L1_CA_OBSERVABLES_CC_H | ||||||
| @@ -24,14 +45,13 @@ | |||||||
| #include "gps_navigation_message.h" | #include "gps_navigation_message.h" | ||||||
|  |  | ||||||
| #include "rinex_2_1_printer.h" | #include "rinex_2_1_printer.h" | ||||||
| #include "gps_l1_ca_ls_pvt.h" |  | ||||||
|  |  | ||||||
| #include "GPS_L1_CA.h" | #include "GPS_L1_CA.h" | ||||||
|  |  | ||||||
| class gps_l1_ca_observables_cc; | class gps_l1_ca_observables_cc; | ||||||
| typedef boost::shared_ptr<gps_l1_ca_observables_cc> gps_l1_ca_observables_cc_sptr; | typedef boost::shared_ptr<gps_l1_ca_observables_cc> gps_l1_ca_observables_cc_sptr; | ||||||
| gps_l1_ca_observables_cc_sptr | gps_l1_ca_observables_cc_sptr | ||||||
| gps_l1_ca_make_observables_cc(unsigned int n_channels, gr_msg_queue_sptr queue, bool dump); | gps_l1_ca_make_observables_cc(unsigned int n_channels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging); | ||||||
|  |  | ||||||
|  |  | ||||||
| class gps_l1_ca_observables_cc : public gr_block { | class gps_l1_ca_observables_cc : public gr_block { | ||||||
| @@ -39,32 +59,24 @@ class gps_l1_ca_observables_cc : public gr_block { | |||||||
| private: | private: | ||||||
|  |  | ||||||
|   friend gps_l1_ca_observables_cc_sptr |   friend gps_l1_ca_observables_cc_sptr | ||||||
|   gps_l1_ca_make_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump); |   gps_l1_ca_make_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging); | ||||||
|  |   gps_l1_ca_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging); | ||||||
|   gps_l1_ca_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump); |  | ||||||
|  |  | ||||||
|   // class private vars |   // class private vars | ||||||
|   gr_msg_queue_sptr d_queue; |   gr_msg_queue_sptr d_queue; | ||||||
|   bool d_dump; |   bool d_dump; | ||||||
|  |   bool d_flag_averaging; | ||||||
|  |   long int d_sample_counter; | ||||||
|   unsigned int d_nchannels; |   unsigned int d_nchannels; | ||||||
|   unsigned long int d_fs_in; |   unsigned long int d_fs_in; | ||||||
|  |   int d_output_rate_ms; | ||||||
|   std::string d_dump_filename; |   std::string d_dump_filename; | ||||||
|   std::ofstream d_dump_file; |   std::ofstream d_dump_file; | ||||||
|  |  | ||||||
|  |   std::deque<double> *d_history_prn_delay_ms; | ||||||
|  |  | ||||||
|   concurrent_queue<gps_navigation_message> *d_nav_queue; // Navigation ephemeris queue |   concurrent_queue<gps_navigation_message> *d_nav_queue; // Navigation ephemeris queue | ||||||
|  |  | ||||||
|   rinex_printer d_rinex_printer; // RINEX printer class |  | ||||||
|  |  | ||||||
|   gps_navigation_message d_last_nav_msg; //last navigation message |  | ||||||
|  |  | ||||||
|   double d_ephemeris_clock_s; |  | ||||||
|   double d_ephemeris_timestamp_ms; |  | ||||||
|  |  | ||||||
|   gps_l1_ca_ls_pvt *d_ls_pvt; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| public: | public: | ||||||
|  |  | ||||||
|   ~gps_l1_ca_observables_cc (); |   ~gps_l1_ca_observables_cc (); | ||||||
|   | |||||||
| @@ -1,3 +1,2 @@ | |||||||
| build-project adapters ; | build-project adapters ; | ||||||
| build-project gnuradio_blocks ; | build-project gnuradio_blocks ; | ||||||
| build-project libs ; |  | ||||||
| @@ -38,6 +38,8 @@ | |||||||
|  |  | ||||||
| #include <string> | #include <string> | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  | #include <fstream> | ||||||
|  |  | ||||||
|  |  | ||||||
| #include <glog/log_severity.h> | #include <glog/log_severity.h> | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| @@ -93,6 +95,34 @@ FileSignalSource::FileSignalSource(ConfigurationInterface* configuration, | |||||||
|             = gr_make_file_source(item_size_, filename_.c_str(), repeat_); |             = gr_make_file_source(item_size_, filename_.c_str(), repeat_); | ||||||
|     DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")"; |     DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")"; | ||||||
|  |  | ||||||
|  |     if (samples_==0) | ||||||
|  |     { | ||||||
|  | 		/*! | ||||||
|  | 		 * BUG workaround: The GNURadio file source does not stop the receiver after reaching the End of File. | ||||||
|  | 		 * A possible solution is to compute the file lenght in samples using file size, excluding the last 100 milliseconds, and enable always the | ||||||
|  | 		 * valve block | ||||||
|  | 		 */ | ||||||
|  | 		std::ifstream file (filename_.c_str(), std::ios::in|std::ios::binary|std::ios::ate); | ||||||
|  | 		std::ifstream::pos_type size; | ||||||
|  | 		if (file.is_open()) | ||||||
|  | 		{ | ||||||
|  | 			size =file.tellg(); | ||||||
|  | 		}else{ | ||||||
|  | 			std::cout<<"file_signal_source: Unable to open the samples file "<<filename_.c_str()<<"\r\n"; | ||||||
|  | 			LOG_AT_LEVEL(WARNING)<<"file_signal_source: Unable to open the samples file "<<filename_.c_str(); | ||||||
|  | 		} | ||||||
|  | 		std::cout<<std::setprecision(16); | ||||||
|  | 		std::cout<<"Processing file "<<filename_<<" containing "<<(double)size<<" [bytes] \r\n"; | ||||||
|  | 		if (size>0) | ||||||
|  | 		{ | ||||||
|  | 			samples_=floor((double)size/(double)item_size())-ceil(0.1*(double)sampling_frequency_); //process all the samples available in the file excluding the last 100 ms | ||||||
|  |  | ||||||
|  | 		} | ||||||
|  |     } | ||||||
|  |     double signal_duration_s; | ||||||
|  |     signal_duration_s=(double)samples_*(1/(double)sampling_frequency_); | ||||||
|  |     DLOG(INFO)<<"Total samples to be processed="<<samples_<<" GNSS signal duration= "<<signal_duration_s<<" [s]"; | ||||||
|  |     std::cout<<"GNSS signal recorded time to be processed: "<<signal_duration_s<<" [s]\r\n"; | ||||||
|     // if samples != 0 then enable a flow valve to stop the process after n samples |     // if samples != 0 then enable a flow valve to stop the process after n samples | ||||||
|     if (samples_ != 0) |     if (samples_ != 0) | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -66,22 +66,13 @@ GpsL1CaTelemetryDecoder::GpsL1CaTelemetryDecoder(ConfigurationInterface* configu | |||||||
|     DLOG(INFO) << "role " << role; |     DLOG(INFO) << "role " << role; | ||||||
|     DLOG(INFO) << "vector length " << vector_length_; |     DLOG(INFO) << "vector length " << vector_length_; | ||||||
|  |  | ||||||
|     item_type_ = configuration->property(role + ".item_type", default_item_type); |  | ||||||
|  |  | ||||||
|     vector_length_ = configuration->property(role + ".vector_length", 2048); |     vector_length_ = configuration->property(role + ".vector_length", 2048); | ||||||
|     dump_ = configuration->property(role + ".dump", false); |     dump_ = configuration->property(role + ".dump", false); | ||||||
|     dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); //unused! |     dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); | ||||||
|  |     int fs_in; | ||||||
|  |     fs_in = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||||
|  |  | ||||||
|  |     telemetry_decoder_ = gps_l1_ca_make_telemetry_decoder_cc(satellite_, 0, (long)fs_in, vector_length_, queue_, dump_); // TODO fix me | ||||||
|     if(item_type_.compare("gr_complex") == 0) |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(gr_complex); |  | ||||||
|             telemetry_decoder_ = gps_l1_ca_make_telemetry_decoder_cc(satellite_, 0, 0, vector_length_, queue_, dump_); // TODO fix me |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             LOG_AT_LEVEL(WARNING) << item_type_ << " unknown navigation item type."; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; |     DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -79,7 +79,7 @@ public: | |||||||
|  |  | ||||||
|     size_t item_size() |     size_t item_size() | ||||||
|     { |     { | ||||||
|         return item_size_; |         return 0; | ||||||
|     } |     } | ||||||
| private: | private: | ||||||
|  |  | ||||||
| @@ -87,7 +87,6 @@ private: | |||||||
|  |  | ||||||
|     int satellite_; |     int satellite_; | ||||||
|     int channel_; |     int channel_; | ||||||
|     size_t item_size_; |  | ||||||
|     unsigned int vector_length_; |     unsigned int vector_length_; | ||||||
|     std::string item_type_; |     std::string item_type_; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,19 +1,36 @@ | |||||||
| /*! | /*! | ||||||
|  * Navigation message demodulator based on the Kay Borre book MATLAB-based GPS receiver |  * \file gps_l1_ca_telemetry_decoder_cc.cc | ||||||
|  |  * \brief Navigation message demodulator based on the Kay Borre book MATLAB-based GPS receiver | ||||||
|  |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| /** | /*! | ||||||
|  * Copyright notice |  * \todo Clean this code and move the telemetri definitions to GPS_L1_CA system definitions file | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Author: Javier Arribas, 2011. jarribas(at)cttc.es |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifdef HAVE_CONFIG_H |  | ||||||
| #include "config.h" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include "gps_l1_ca_telemetry_decoder_cc.h" | #include "gps_l1_ca_telemetry_decoder_cc.h" | ||||||
|  |  | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
| @@ -27,8 +44,11 @@ | |||||||
| #include <glog/log_severity.h> | #include <glog/log_severity.h> | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
|  |  | ||||||
| using google::LogMessage; |  | ||||||
|  |  | ||||||
|  | using google::LogMessage; | ||||||
|  | /*! | ||||||
|  |  * \todo name and move the magic numbers to GPS_L1_CA.h | ||||||
|  |  */ | ||||||
| gps_l1_ca_telemetry_decoder_cc_sptr | gps_l1_ca_telemetry_decoder_cc_sptr | ||||||
| gps_l1_ca_make_telemetry_decoder_cc(unsigned int satellite, long if_freq, long fs_in, unsigned | gps_l1_ca_make_telemetry_decoder_cc(unsigned int satellite, long if_freq, long fs_in, unsigned | ||||||
|     int vector_length, gr_msg_queue_sptr queue, bool dump) { |     int vector_length, gr_msg_queue_sptr queue, bool dump) { | ||||||
| @@ -47,7 +67,7 @@ void gps_l1_ca_telemetry_decoder_cc::forecast (int noutput_items, | |||||||
|  |  | ||||||
| gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(unsigned int satellite, long if_freq, long fs_in, unsigned | gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(unsigned int satellite, long if_freq, long fs_in, unsigned | ||||||
|     int vector_length, gr_msg_queue_sptr queue, bool dump) : |     int vector_length, gr_msg_queue_sptr queue, bool dump) : | ||||||
|     gr_block ("gps_navigation_cc", gr_make_io_signature (5, 5, sizeof(float)), |     gr_block ("gps_navigation_cc", gr_make_io_signature (5, 5, sizeof(double)), | ||||||
|         gr_make_io_signature(1, 1, sizeof(gnss_synchro))) { |         gr_make_io_signature(1, 1, sizeof(gnss_synchro))) { | ||||||
|   // initialize internal vars |   // initialize internal vars | ||||||
|   d_queue = queue; |   d_queue = queue; | ||||||
| @@ -55,6 +75,9 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(unsigned int sate | |||||||
|   d_satellite = satellite; |   d_satellite = satellite; | ||||||
|   d_vector_length = vector_length; |   d_vector_length = vector_length; | ||||||
|   d_samples_per_bit=20; // it is exactly 1000*(1/50)=20 |   d_samples_per_bit=20; // it is exactly 1000*(1/50)=20 | ||||||
|  |   d_fs_in=fs_in; | ||||||
|  |   d_preamble_duration_seconds=(1.0/(float)GPS_CA_TELEMETRY_RATE_BITS_SECOND)*(float)GPS_CA_PREAMBLE_LENGTH_BITS; | ||||||
|  |   //std::cout<<"d_preamble_duration_seconds="<<d_preamble_duration_seconds<<"\r\n"; | ||||||
|   // set the preamble |   // set the preamble | ||||||
|   unsigned short int preambles_bits[8]=GPS_PREAMBLE; |   unsigned short int preambles_bits[8]=GPS_PREAMBLE; | ||||||
|  |  | ||||||
| @@ -77,6 +100,7 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(unsigned int sate | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   d_sample_counter=0; |   d_sample_counter=0; | ||||||
|  |   d_preamble_code_phase_seconds=0; | ||||||
|   d_stat=0; |   d_stat=0; | ||||||
|   d_preamble_index=0; |   d_preamble_index=0; | ||||||
|   d_symbol_accumulator_counter=0; |   d_symbol_accumulator_counter=0; | ||||||
| @@ -101,57 +125,88 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i | |||||||
|     gr_vector_const_void_star &input_items,	gr_vector_void_star &output_items) { |     gr_vector_const_void_star &input_items,	gr_vector_void_star &output_items) { | ||||||
|   int corr_value=0; |   int corr_value=0; | ||||||
|   int preamble_diff; |   int preamble_diff; | ||||||
|  |  | ||||||
|   gnss_synchro gps_synchro; //structure to save the synchronization information |   gnss_synchro gps_synchro; //structure to save the synchronization information | ||||||
|   gnss_synchro **out = (gnss_synchro **) &output_items[0]; |   gnss_synchro **out = (gnss_synchro **) &output_items[0]; | ||||||
|   d_sample_counter++; //count for the processed samples |   d_sample_counter++; //count for the processed samples | ||||||
|  |  | ||||||
|   const float **in = (const float **)  &input_items[0]; //Get the input samples pointer |   const double **in = (const double **)  &input_items[0]; //Get the input samples pointer | ||||||
|  | 	// ########### Output the tracking data to navigation and PVT ########## | ||||||
|  | 	// Output channel 0: Prompt correlator output Q | ||||||
|  | //	*out[0]=(double)d_Prompt.real(); | ||||||
|  | //	// Output channel 1: Prompt correlator output I | ||||||
|  | //	*out[1]=(double)d_Prompt.imag(); | ||||||
|  | //	// Output channel 2: PRN absolute delay [s] | ||||||
|  | //	*out[2]=d_sample_counter_seconds; | ||||||
|  | //	// Output channel 3: d_acc_carrier_phase_rad [rad] | ||||||
|  | //	*out[3]=(double)d_acc_carrier_phase_rad; | ||||||
|  | //	// Output channel 4: PRN code phase [s] | ||||||
|  | //	*out[4]=(double)d_code_phase_samples*(1/(float)d_fs_in); | ||||||
|  |  | ||||||
|  |   /*! | ||||||
|  |    * \todo Check the HOW GPS time computation, taking into account that the preamble correlation last 160 symbols, which is 160 ms in GPS CA L1 | ||||||
|  |    */ | ||||||
|  |   // FIFO history to get the exact timestamp of the first symbol of the preamble | ||||||
|  | //  if (d_prn_start_sample_history.size()<160) | ||||||
|  | //  { | ||||||
|  | //	  // fill the queue | ||||||
|  | //	  d_prn_start_sample_history.push_front(in[2][0]); | ||||||
|  | //	  consume_each(1); //one by one | ||||||
|  | //	  return 1; | ||||||
|  | //  }else{ | ||||||
|  | //	  d_prn_start_sample_history.pop_back(); | ||||||
|  | //	  d_prn_start_sample_history.push_front(in[2][0]); | ||||||
|  | //  } | ||||||
|   // TODO Optimize me! |   // TODO Optimize me! | ||||||
|   //******* preamble correlation ******** |   //******* preamble correlation ******** | ||||||
|   for (unsigned int i=0;i<d_samples_per_bit*8;i++){ |   for (unsigned int i=0;i<d_samples_per_bit*8;i++){ | ||||||
|     if (in[1][i] <= 0)	// symbols clipping |     if (in[1][i] < 0)	// symbols clipping | ||||||
|       { |       { | ||||||
|       corr_value-=d_preambles_symbols[i]; |       corr_value-=d_preambles_symbols[i]; | ||||||
|       }else{ |       }else{ | ||||||
|         corr_value+=d_preambles_symbols[i]; |         corr_value+=d_preambles_symbols[i]; | ||||||
|       } |       } | ||||||
|   } |   } | ||||||
|  |   d_flag_preamble=false; | ||||||
|   //******* frame sync ****************** |   //******* frame sync ****************** | ||||||
|   if (abs(corr_value)>=160){ |   if (abs(corr_value)>=160){ | ||||||
|     //TODO: Rewrite with state machine | 	  //TODO: Rewrite with state machine | ||||||
|     if (d_stat==0) | 	  if (d_stat==0) | ||||||
|       { | 	  { | ||||||
|       d_GPS_FSM.Event_gps_word_preamble(); | 		  d_GPS_FSM.Event_gps_word_preamble(); | ||||||
|       d_preamble_index=d_sample_counter;//record the preamble sample stamp | 		  d_preamble_index=d_sample_counter;//record the preamble sample stamp | ||||||
|       std::cout<<"Pre-detection SAT "<<this->d_satellite<<std::endl; | 		  std::cout<<"Preamble detection for SAT "<<d_satellite<<std::endl; | ||||||
|       d_symbol_accumulator=0; //sync the symbol to bits integrator | 		  d_symbol_accumulator=0; //sync the symbol to bits integrator | ||||||
|       d_symbol_accumulator_counter=0; | 		  d_symbol_accumulator_counter=0; | ||||||
|       d_frame_bit_index=8; | 		  d_frame_bit_index=8; | ||||||
|       d_stat=1; // enter into frame pre-detection status | 		  d_stat=1; // enter into frame pre-detection status | ||||||
|       }else if (d_stat==1) //check 6 seconds of preample separation | 	  }else if (d_stat==1) //check 6 seconds of preample separation | ||||||
|         { | 	  { | ||||||
|         preamble_diff=abs(d_sample_counter-d_preamble_index); | 		  preamble_diff=abs(d_sample_counter-d_preamble_index); | ||||||
|         if (abs(preamble_diff-6000)<1) | 		  if (abs(preamble_diff-6000)<1) | ||||||
|           { | 		  { | ||||||
|           d_GPS_FSM.Event_gps_word_preamble(); | 			  d_GPS_FSM.Event_gps_word_preamble(); | ||||||
|           d_preamble_index=d_sample_counter;//record the preamble sample stamp (t_P) | 			  d_flag_preamble=true; | ||||||
|           d_preamble_phase=in[2][0]; //record the PRN start sample index associated to the preamble | 			  d_preamble_index=d_sample_counter;//record the preamble sample stamp (t_P) | ||||||
|  | 			  d_preamble_time_seconds=in[2][0]-d_preamble_duration_seconds; //record the PRN start sample index associated to the preamble | ||||||
|  | 			  d_preamble_code_phase_seconds=in[4][0]; | ||||||
|  |  | ||||||
|           if (!d_flag_frame_sync){ | 			  if (!d_flag_frame_sync){ | ||||||
|             d_flag_frame_sync=true; | 				  d_flag_frame_sync=true; | ||||||
|             std::cout<<" Frame sync SAT "<<this->d_satellite<<" with preamble start at "<<in[2][0]<<" [ms]"<<std::endl; | 				  std::cout<<" Frame sync SAT "<<d_satellite<<" with preamble start at "<<d_preamble_time_seconds<<" [s]"<<std::endl; | ||||||
|           } | 			  } | ||||||
|           }else | 		  } | ||||||
|             { | 	  } | ||||||
|             if (preamble_diff>7000){ |   }else{ | ||||||
|               std::cout<<"lost of frame sync SAT "<<this->d_satellite<<std::endl; | 	  if (d_stat==1) | ||||||
|               d_stat=0; //lost of frame sync | 	  { | ||||||
|               d_flag_frame_sync=false; | 		  preamble_diff=d_sample_counter-d_preamble_index; | ||||||
|             } | 		  if (preamble_diff>6001){ | ||||||
|             } | 			  std::cout<<"Lost of frame sync SAT "<<this->d_satellite<<" preamble_diff= "<<preamble_diff<<std::endl; | ||||||
|         } | 			  d_stat=0; //lost of frame sync | ||||||
|  | 			  d_flag_frame_sync=false; | ||||||
|  | 		  } | ||||||
|  | 	  } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   //******* code error accumulator ***** |   //******* code error accumulator ***** | ||||||
| @@ -194,7 +249,7 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i | |||||||
|         } |         } | ||||||
|       if (gps_word_parityCheck(d_GPS_frame_4bytes)) { |       if (gps_word_parityCheck(d_GPS_frame_4bytes)) { | ||||||
|         memcpy(&d_GPS_FSM.d_GPS_frame_4bytes,&d_GPS_frame_4bytes,sizeof(char)*4); |         memcpy(&d_GPS_FSM.d_GPS_frame_4bytes,&d_GPS_frame_4bytes,sizeof(char)*4); | ||||||
|         d_GPS_FSM.d_preamble_time_ms=d_preamble_phase; |         d_GPS_FSM.d_preamble_time_ms=d_preamble_time_seconds*1000.0; | ||||||
|         d_GPS_FSM.Event_gps_word_valid(); |         d_GPS_FSM.Event_gps_word_valid(); | ||||||
|         d_flag_parity=true; |         d_flag_parity=true; | ||||||
|       }else{ |       }else{ | ||||||
| @@ -209,21 +264,18 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i | |||||||
|     } |     } | ||||||
|  |  | ||||||
|   // output the frame |   // output the frame | ||||||
|   consume_each(1); //one by one | 	consume_each(1); //one by one | ||||||
|  |  | ||||||
|   if ((d_sample_counter%NAVIGATION_OUTPUT_RATE_MS)==0) | 	gps_synchro.valid_word=(d_flag_frame_sync==true and d_flag_parity==true); | ||||||
|     { | 	gps_synchro.flag_preamble=d_flag_preamble; | ||||||
|     gps_synchro.valid_word=(d_flag_frame_sync==true and d_flag_parity==true); | 	gps_synchro.preamble_delay_ms=d_preamble_time_seconds*1000.0; | ||||||
|     //gps_synchro.preamble_delay_ms=(float)d_preamble_index; | 	gps_synchro.prn_delay_ms=(in[2][0]-d_preamble_duration_seconds)*1000.0; | ||||||
|     gps_synchro.preamble_delay_ms=(float)d_preamble_index; | 	gps_synchro.preamble_code_phase_ms=d_preamble_code_phase_seconds*1000.0; | ||||||
|     gps_synchro.prn_delay_ms=in[3][0]; | 	gps_synchro.preamble_code_phase_correction_ms=(in[4][0]-d_preamble_code_phase_seconds)*1000.0; | ||||||
|     gps_synchro.satellite_PRN=d_satellite; | 	gps_synchro.satellite_PRN=d_satellite; | ||||||
|     gps_synchro.channel_ID=d_channel; | 	gps_synchro.channel_ID=d_channel; | ||||||
|     *out[0]=gps_synchro; | 	*out[0]=gps_synchro; | ||||||
|     return 1; | 	return 1; | ||||||
|     }else{ |  | ||||||
|       return 0; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,12 +1,31 @@ | |||||||
|  | /*! | ||||||
| /** |  * \file gps_l1_ca_telemetry_decoder_cc.h | ||||||
|  * Copyright notice |  * \brief Navigation message demodulator based on the Kay Borre book MATLAB-based GPS receiver | ||||||
|  |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Author: Javier Arribas, 2011. jarribas(at)cttc.es |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifndef GPS_L1_CA_TELEMETRY_DECODER_CC_H | #ifndef GPS_L1_CA_TELEMETRY_DECODER_CC_H | ||||||
| #define	GPS_L1_CA_TELEMETRY_DECODER_CC_H | #define	GPS_L1_CA_TELEMETRY_DECODER_CC_H | ||||||
|  |  | ||||||
| @@ -63,8 +82,11 @@ private: | |||||||
|   unsigned int d_GPS_frame_4bytes; |   unsigned int d_GPS_frame_4bytes; | ||||||
|   unsigned int d_prev_GPS_frame_4bytes; |   unsigned int d_prev_GPS_frame_4bytes; | ||||||
|   bool d_flag_parity; |   bool d_flag_parity; | ||||||
|  |   bool d_flag_preamble; | ||||||
|   int d_word_number; |   int d_word_number; | ||||||
|  |  | ||||||
|  |   long d_fs_in; | ||||||
|  |   double d_preamble_duration_seconds; | ||||||
|   // navigation message vars |   // navigation message vars | ||||||
|   gps_navigation_message d_nav; |   gps_navigation_message d_nav; | ||||||
|   GpsL1CaSubframeFsm d_GPS_FSM; |   GpsL1CaSubframeFsm d_GPS_FSM; | ||||||
| @@ -76,7 +98,10 @@ private: | |||||||
|   int d_satellite; |   int d_satellite; | ||||||
|   int d_channel; |   int d_channel; | ||||||
|  |  | ||||||
|   float d_preamble_phase; |   //std::deque<double> d_prn_start_sample_history; | ||||||
|  |  | ||||||
|  |   double d_preamble_time_seconds; | ||||||
|  |   double d_preamble_code_phase_seconds; | ||||||
|  |  | ||||||
|   std::string d_dump_filename; |   std::string d_dump_filename; | ||||||
|   std::ofstream d_dump_file; |   std::ofstream d_dump_file; | ||||||
|   | |||||||
| @@ -144,16 +144,17 @@ void GpsL1CaSubframeFsm::gps_subframe_to_nav_msg() | |||||||
| { | { | ||||||
|   int subframe_ID; |   int subframe_ID; | ||||||
|   // NEW GPS SUBFRAME HAS ARRIVED! |   // NEW GPS SUBFRAME HAS ARRIVED! | ||||||
|  |  | ||||||
|   subframe_ID=d_nav.subframe_decoder(this->d_subframe); //decode the subframe |   subframe_ID=d_nav.subframe_decoder(this->d_subframe); //decode the subframe | ||||||
|  |   std::cout<<"NAVIGATION FSM: received subframe "<<subframe_ID<<" for satellite "<<d_nav.d_satellite_PRN<<std::endl; | ||||||
|   d_nav.d_satellite_PRN=d_satellite_PRN; |   d_nav.d_satellite_PRN=d_satellite_PRN; | ||||||
|   d_nav.d_channel_ID=d_channel_ID; |   d_nav.d_channel_ID=d_channel_ID; | ||||||
|   if (subframe_ID==1) { |   if (subframe_ID==1) { | ||||||
|     d_nav.d_subframe1_timestamp_ms=this->d_preamble_time_ms-6002; |     d_nav.d_subframe1_timestamp_ms=this->d_preamble_time_ms; | ||||||
|     std::cout<<"FSM: set subframe1 preamble timestamp for sat "<<d_nav.d_satellite_PRN<<std::endl; |     //std::cout<<"NAVIGATION FSM: set subframe 1 preamble timestamp for satellite "<<d_nav.d_satellite_PRN<<std::endl; | ||||||
|   } |   } | ||||||
|   //TODO: change to subframe 5 |   /*! | ||||||
|  |    * \todo change satellite validation to subframe 5 because it will have a complete set of ephemeris parameters | ||||||
|  |    */ | ||||||
|   if (subframe_ID==3) { // if the subframe is the 5th, then |   if (subframe_ID==3) { // if the subframe is the 5th, then | ||||||
|     if (d_nav.satellite_validation()) // if all the satellite ephemeris parameters are good, then |     if (d_nav.satellite_validation()) // if all the satellite ephemeris parameters are good, then | ||||||
|       { |       { | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "gps_l1_ca_dll_fll_pll_tracking.h" | #include "gps_l1_ca_dll_fll_pll_tracking.h" | ||||||
|  | #include "GPS_L1_CA.h" | ||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
|  |  | ||||||
| #include <gnuradio/gr_io_signature.h> | #include <gnuradio/gr_io_signature.h> | ||||||
| @@ -71,8 +71,8 @@ GpsL1CaDllFllPllTracking::GpsL1CaDllFllPllTracking( | |||||||
|     int order; |     int order; | ||||||
|  |  | ||||||
|     item_type = configuration->property(role + ".item_type",default_item_type); |     item_type = configuration->property(role + ".item_type",default_item_type); | ||||||
|     vector_length = configuration->property(role + ".vector_length", 2048); |     //vector_length = configuration->property(role + ".vector_length", 2048); | ||||||
|     fs_in = configuration->property(role + ".fs_in", 2048000); |     fs_in = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||||
|     f_if = configuration->property(role + ".if", 0); |     f_if = configuration->property(role + ".if", 0); | ||||||
|     dump = configuration->property(role + ".dump", false); |     dump = configuration->property(role + ".dump", false); | ||||||
|     order = configuration->property(role + ".order", 2); |     order = configuration->property(role + ".order", 2); | ||||||
| @@ -81,16 +81,18 @@ GpsL1CaDllFllPllTracking::GpsL1CaDllFllPllTracking( | |||||||
|     dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); |     dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); | ||||||
|     early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); |     early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); | ||||||
|  |  | ||||||
|     std::string default_dump_filename = "./tracking.dat"; |     std::string default_dump_filename = "./track_ch"; | ||||||
|     dump_filename = configuration->property(role + ".dump_filename", |     dump_filename = configuration->property(role + ".dump_filename", | ||||||
|             default_dump_filename); //unused! |             default_dump_filename); //unused! | ||||||
|  |  | ||||||
|  |     vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); | ||||||
|  |  | ||||||
|     //################# MAKE TRACKING GNURadio object ################### |     //################# MAKE TRACKING GNURadio object ################### | ||||||
|     if (item_type.compare("gr_complex") == 0) |     if (item_type.compare("gr_complex") == 0) | ||||||
|     { |     { | ||||||
|         item_size_ = sizeof(gr_complex); |         item_size_ = sizeof(gr_complex); | ||||||
|         tracking_ = gps_l1_ca_dll_fll_pll_make_tracking_cc(satellite_, f_if, |         tracking_ = gps_l1_ca_dll_fll_pll_make_tracking_cc(satellite_, f_if, | ||||||
|                 fs_in, vector_length, queue_, dump, order, fll_bw_hz, pll_bw_hz,dll_bw_hz,early_late_space_chips); |                 fs_in, vector_length, queue_, dump, dump_filename, order, fll_bw_hz, pll_bw_hz,dll_bw_hz,early_late_space_chips); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "gps_l1_ca_dll_pll_tracking.h" | #include "gps_l1_ca_dll_pll_tracking.h" | ||||||
|  | #include "GPS_L1_CA.h" | ||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
|  |  | ||||||
| #include <gnuradio/gr_io_signature.h> | #include <gnuradio/gr_io_signature.h> | ||||||
| @@ -69,24 +69,26 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( | |||||||
|     float early_late_space_chips; |     float early_late_space_chips; | ||||||
|  |  | ||||||
|     item_type = configuration->property(role + ".item_type",default_item_type); |     item_type = configuration->property(role + ".item_type",default_item_type); | ||||||
|     vector_length = configuration->property(role + ".vector_length", 2048); |     //vector_length = configuration->property(role + ".vector_length", 2048); | ||||||
|     fs_in = configuration->property(role + ".fs_in", 2048000); |     fs_in = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||||
|     f_if = configuration->property(role + ".if", 0); |     f_if = configuration->property(role + ".if", 0); | ||||||
|     dump = configuration->property(role + ".dump", false); |     dump = configuration->property(role + ".dump", false); | ||||||
|     pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); |     pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); | ||||||
|     dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); |     dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); | ||||||
|     early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); |     early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); | ||||||
|  |  | ||||||
|     std::string default_dump_filename = "./tracking.dat"; |     std::string default_dump_filename = "./track_ch"; | ||||||
|     dump_filename = configuration->property(role + ".dump_filename", |     dump_filename = configuration->property(role + ".dump_filename", | ||||||
|             default_dump_filename); //unused! |             default_dump_filename); //unused! | ||||||
|  |  | ||||||
|  |     vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); | ||||||
|  |  | ||||||
|     //################# MAKE TRACKING GNURadio object ################### |     //################# MAKE TRACKING GNURadio object ################### | ||||||
|     if (item_type.compare("gr_complex") == 0) |     if (item_type.compare("gr_complex") == 0) | ||||||
|     { |     { | ||||||
|         item_size_ = sizeof(gr_complex); |         item_size_ = sizeof(gr_complex); | ||||||
|         tracking_ = gps_l1_ca_dll_pll_make_tracking_cc(satellite_, f_if, |         tracking_ = gps_l1_ca_dll_pll_make_tracking_cc(satellite_, f_if, | ||||||
|                 fs_in, vector_length, queue_, dump,pll_bw_hz,dll_bw_hz,early_late_space_chips); |                 fs_in, vector_length, queue_, dump, dump_filename, pll_bw_hz,dll_bw_hz,early_late_space_chips); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -56,15 +56,17 @@ | |||||||
|  * \todo Include in definition header file |  * \todo Include in definition header file | ||||||
|  */ |  */ | ||||||
| #define CN0_ESTIMATION_SAMPLES 10 | #define CN0_ESTIMATION_SAMPLES 10 | ||||||
|  | #define MINIMUM_VALID_CN0 25 | ||||||
|  | #define MAXIMUM_LOCK_FAIL_COUNTER 200 | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
|  |  | ||||||
| gps_l1_ca_dll_fll_pll_tracking_cc_sptr | gps_l1_ca_dll_fll_pll_tracking_cc_sptr | ||||||
| gps_l1_ca_dll_fll_pll_make_tracking_cc(unsigned int satellite, long if_freq, long fs_in, unsigned | gps_l1_ca_dll_fll_pll_make_tracking_cc(unsigned int satellite, long if_freq, long fs_in, unsigned | ||||||
| 			int vector_length, gr_msg_queue_sptr queue, bool dump, int order, float fll_bw_hz, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) { | 			int vector_length, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int order, float fll_bw_hz, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) { | ||||||
|  |  | ||||||
| 	return gps_l1_ca_dll_fll_pll_tracking_cc_sptr(new gps_l1_ca_dll_fll_pll_tracking_cc(satellite, if_freq, | 	return gps_l1_ca_dll_fll_pll_tracking_cc_sptr(new gps_l1_ca_dll_fll_pll_tracking_cc(satellite, if_freq, | ||||||
| 			fs_in, vector_length, queue, dump, order, fll_bw_hz, pll_bw_hz,dll_bw_hz,early_late_space_chips)); | 			fs_in, vector_length, queue, dump, dump_filename, order, fll_bw_hz, pll_bw_hz,dll_bw_hz,early_late_space_chips)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void gps_l1_ca_dll_fll_pll_tracking_cc::forecast (int noutput_items, | void gps_l1_ca_dll_fll_pll_tracking_cc::forecast (int noutput_items, | ||||||
| @@ -73,9 +75,9 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::forecast (int noutput_items, | |||||||
| } | } | ||||||
|  |  | ||||||
| gps_l1_ca_dll_fll_pll_tracking_cc::gps_l1_ca_dll_fll_pll_tracking_cc(unsigned int satellite, long if_freq, long fs_in, unsigned | gps_l1_ca_dll_fll_pll_tracking_cc::gps_l1_ca_dll_fll_pll_tracking_cc(unsigned int satellite, long if_freq, long fs_in, unsigned | ||||||
| 		int vector_length, gr_msg_queue_sptr queue, bool dump, int order, float fll_bw_hz, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) : | 		int vector_length, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int order, float fll_bw_hz, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) : | ||||||
| 	    gr_block ("gps_l1_ca_dll_fll_pll_tracking_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)), | 	    gr_block ("gps_l1_ca_dll_fll_pll_tracking_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)), | ||||||
| 	              gr_make_io_signature(5, 5, sizeof(float))) { | 	              gr_make_io_signature(5, 5, sizeof(double))) { | ||||||
| 		//gr_sync_decimator ("gps_l1_ca_dll_pll_tracking_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)), | 		//gr_sync_decimator ("gps_l1_ca_dll_pll_tracking_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)), | ||||||
| 		//		gr_make_io_signature(3, 3, sizeof(float)),vector_length) { | 		//		gr_make_io_signature(3, 3, sizeof(float)),vector_length) { | ||||||
| 	// initialize internal vars | 	// initialize internal vars | ||||||
| @@ -86,6 +88,7 @@ gps_l1_ca_dll_fll_pll_tracking_cc::gps_l1_ca_dll_fll_pll_tracking_cc(unsigned in | |||||||
| 	d_fs_in = fs_in; | 	d_fs_in = fs_in; | ||||||
| 	d_vector_length = vector_length; | 	d_vector_length = vector_length; | ||||||
| 	d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips) | 	d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips) | ||||||
|  |     d_dump_filename=dump_filename; | ||||||
|  |  | ||||||
| 	// Initialize tracking variables ========================================== | 	// Initialize tracking variables ========================================== | ||||||
| 	d_carrier_loop_filter.set_params(fll_bw_hz,pll_bw_hz,order); | 	d_carrier_loop_filter.set_params(fll_bw_hz,pll_bw_hz,order); | ||||||
| @@ -101,6 +104,7 @@ gps_l1_ca_dll_fll_pll_tracking_cc::gps_l1_ca_dll_fll_pll_tracking_cc(unsigned in | |||||||
|  |  | ||||||
|     // sample synchronization |     // sample synchronization | ||||||
|     d_sample_counter=0; |     d_sample_counter=0; | ||||||
|  |     d_sample_counter_seconds=0; | ||||||
|     d_acq_sample_stamp=0; |     d_acq_sample_stamp=0; | ||||||
|     d_last_seg=0;// this is for debug output only |     d_last_seg=0;// this is for debug output only | ||||||
|  |  | ||||||
| @@ -125,8 +129,9 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::start_tracking(){ | |||||||
| 	 */ | 	 */ | ||||||
| 	unsigned long int acq_trk_diff_samples; | 	unsigned long int acq_trk_diff_samples; | ||||||
| 	float acq_trk_diff_seconds; | 	float acq_trk_diff_seconds; | ||||||
| 	acq_trk_diff_samples=d_sample_counter-d_acq_sample_stamp-d_vector_length; | 	acq_trk_diff_samples=d_sample_counter-d_acq_sample_stamp;//-d_vector_length; | ||||||
| 	acq_trk_diff_seconds=acq_trk_diff_samples/(float)d_fs_in; | 	//std::cout<<"acq_trk_diff_samples="<<acq_trk_diff_samples<<"\r\n"; | ||||||
|  | 	acq_trk_diff_seconds=(float)acq_trk_diff_samples/(float)d_fs_in; | ||||||
| 	//doppler effect | 	//doppler effect | ||||||
| 	// Fd=(C/(C+Vr))*F | 	// Fd=(C/(C+Vr))*F | ||||||
| 	float radial_velocity; | 	float radial_velocity; | ||||||
| @@ -140,15 +145,24 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::start_tracking(){ | |||||||
| 	T_prn_mod_seconds=T_chip_mod_seconds*GPS_L1_CA_CODE_LENGTH_CHIPS; | 	T_prn_mod_seconds=T_chip_mod_seconds*GPS_L1_CA_CODE_LENGTH_CHIPS; | ||||||
| 	T_prn_mod_samples=T_prn_mod_seconds*(float)d_fs_in; | 	T_prn_mod_samples=T_prn_mod_seconds*(float)d_fs_in; | ||||||
|     d_next_prn_length_samples=round(T_prn_mod_samples); |     d_next_prn_length_samples=round(T_prn_mod_samples); | ||||||
| 	//compute the code phase chips prediction |  | ||||||
| 	float delta_T_prn_samples; |  | ||||||
| 	float delay_correction_samples; |     float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS/GPS_L1_CA_CODE_RATE_HZ; | ||||||
| 	delta_T_prn_samples=fmod((float)acq_trk_diff_samples,T_prn_mod_samples); |     float T_prn_true_samples = T_prn_true_seconds*(float)d_fs_in; | ||||||
| 	delay_correction_samples=T_prn_mod_samples-delta_T_prn_samples; |     float T_prn_diff_seconds; | ||||||
| 	d_acq_code_phase_samples=d_acq_code_phase_samples-delay_correction_samples; |     T_prn_diff_seconds=T_prn_true_seconds-T_prn_mod_seconds; | ||||||
| 	if (d_acq_code_phase_samples<0){ |     float N_prn_diff; | ||||||
| 		d_acq_code_phase_samples=d_acq_code_phase_samples+T_prn_mod_samples; |     N_prn_diff=acq_trk_diff_seconds/T_prn_true_seconds; | ||||||
| 	} |     float corrected_acq_phase_samples,delay_correction_samples; | ||||||
|  |     corrected_acq_phase_samples=fmod((d_acq_code_phase_samples+T_prn_diff_seconds*N_prn_diff*(float)d_fs_in),T_prn_true_samples); | ||||||
|  |  | ||||||
|  |     if (corrected_acq_phase_samples<0) | ||||||
|  |     { | ||||||
|  |     	corrected_acq_phase_samples=T_prn_mod_samples+corrected_acq_phase_samples; | ||||||
|  |     } | ||||||
|  | 	delay_correction_samples=d_acq_code_phase_samples-corrected_acq_phase_samples; | ||||||
|  | 	d_acq_code_phase_samples=corrected_acq_phase_samples; | ||||||
|  |  | ||||||
| 	d_carrier_doppler_hz=d_acq_carrier_doppler_hz; | 	d_carrier_doppler_hz=d_acq_carrier_doppler_hz; | ||||||
| 	// DLL/PLL filter initialization | 	// DLL/PLL filter initialization | ||||||
| 	d_carrier_loop_filter.initialize(d_acq_carrier_doppler_hz); | 	d_carrier_loop_filter.initialize(d_acq_carrier_doppler_hz); | ||||||
| @@ -168,24 +182,8 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::start_tracking(){ | |||||||
| 	d_next_rem_code_phase_samples=0; | 	d_next_rem_code_phase_samples=0; | ||||||
| 	d_acc_carrier_phase_rad=0; | 	d_acc_carrier_phase_rad=0; | ||||||
|  |  | ||||||
| 	// ############# ENABLE DATA FILE LOG ################# | 	d_code_phase_samples = d_acq_code_phase_samples; | ||||||
| 	if (d_dump==true) |  | ||||||
| 	{ |  | ||||||
| 		if (d_dump_file.is_open()==false) |  | ||||||
| 		{ |  | ||||||
| 			try { |  | ||||||
| 				d_dump_filename="track_ch"; //base path and name for the tracking log file |  | ||||||
| 				d_dump_filename.append(boost::lexical_cast<std::string>(d_channel)); |  | ||||||
| 				d_dump_filename.append(".dat"); |  | ||||||
| 				d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit ); |  | ||||||
| 				d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); |  | ||||||
| 				std::cout<<"Tracking dump enabled on channel "<<d_channel<<" Log file: "<<d_dump_filename.c_str()<<std::endl; |  | ||||||
| 			} |  | ||||||
| 			catch (std::ifstream::failure e) { |  | ||||||
| 				std::cout << "channel "<<d_channel <<" Exception opening trk dump file "<<e.what()<<"\r\n"; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	// DEBUG OUTPUT | 	// DEBUG OUTPUT | ||||||
| 	std::cout<<"Tracking start on channel "<<d_channel<<" for satellite ID* "<< this->d_satellite<< std::endl; | 	std::cout<<"Tracking start on channel "<<d_channel<<" for satellite ID* "<< this->d_satellite<< std::endl; | ||||||
| 	DLOG(INFO) << "Start tracking for satellite "<<this->d_satellite<<" received "; | 	DLOG(INFO) << "Start tracking for satellite "<<this->d_satellite<<" received "; | ||||||
| @@ -194,7 +192,7 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::start_tracking(){ | |||||||
| 	d_pull_in=true; | 	d_pull_in=true; | ||||||
| 	d_enable_tracking=true; | 	d_enable_tracking=true; | ||||||
|  |  | ||||||
| 	std::cout<<"PULL-IN Doppler [Hz]= "<<d_carrier_doppler_hz<<" PULL-IN Code Phase [chips]= "<<d_acq_code_phase_samples<<"\r\n"; | 	std::cout<<"PULL-IN Doppler [Hz]= "<<d_carrier_doppler_hz<<" Code Phase correction [samples]="<<delay_correction_samples<<" PULL-IN Code Phase [samples]= "<<d_acq_code_phase_samples<<"\r\n"; | ||||||
| } | } | ||||||
|  |  | ||||||
| void gps_l1_ca_dll_fll_pll_tracking_cc::update_local_code() | void gps_l1_ca_dll_fll_pll_tracking_cc::update_local_code() | ||||||
| @@ -218,12 +216,13 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::update_local_code() | |||||||
|         d_late_code[i] = d_ca_code[associated_chip_index]; |         d_late_code[i] = d_ca_code[associated_chip_index]; | ||||||
|         tcode_chips=tcode_chips+code_phase_step_chips; |         tcode_chips=tcode_chips+code_phase_step_chips; | ||||||
|     } |     } | ||||||
|  | 	//d_code_phase_samples=d_code_phase_samples+(float)d_fs_in*GPS_L1_CA_CODE_LENGTH_CHIPS*(1/d_code_freq_hz-1/GPS_L1_CA_CODE_RATE_HZ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void gps_l1_ca_dll_fll_pll_tracking_cc::update_local_carrier() | void gps_l1_ca_dll_fll_pll_tracking_cc::update_local_carrier() | ||||||
| { | { | ||||||
|     float phase, phase_step; |     float phase, phase_step; | ||||||
|     phase_step = (float)TWO_PI*d_carrier_doppler_hz/d_fs_in; |     phase_step = (float)TWO_PI*d_carrier_doppler_hz/(float)d_fs_in; | ||||||
|     phase=d_rem_carr_phase; |     phase=d_rem_carr_phase; | ||||||
|     for(int i = 0; i < d_current_prn_length_samples; i++) { |     for(int i = 0; i < d_current_prn_length_samples; i++) { | ||||||
|         d_carr_sign[i] = gr_complex(cos(phase),sin(phase)); |         d_carr_sign[i] = gr_complex(cos(phase),sin(phase)); | ||||||
| @@ -235,12 +234,12 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::update_local_carrier() | |||||||
|  |  | ||||||
| gps_l1_ca_dll_fll_pll_tracking_cc::~gps_l1_ca_dll_fll_pll_tracking_cc() { | gps_l1_ca_dll_fll_pll_tracking_cc::~gps_l1_ca_dll_fll_pll_tracking_cc() { | ||||||
| 	d_dump_file.close(); | 	d_dump_file.close(); | ||||||
|     delete d_ca_code; |     delete[] d_ca_code; | ||||||
|     delete d_early_code; |     delete[] d_early_code; | ||||||
|     delete d_prompt_code; |     delete[] d_prompt_code; | ||||||
|     delete d_late_code; |     delete[] d_late_code; | ||||||
|     delete d_carr_sign; |     delete[] d_carr_sign; | ||||||
|     delete d_Prompt_buffer; |     delete[] d_Prompt_buffer; | ||||||
| } | } | ||||||
|  |  | ||||||
| /*! Tracking signal processing | /*! Tracking signal processing | ||||||
| @@ -250,23 +249,63 @@ gps_l1_ca_dll_fll_pll_tracking_cc::~gps_l1_ca_dll_fll_pll_tracking_cc() { | |||||||
| int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vector_int &ninput_items, | int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vector_int &ninput_items, | ||||||
|     gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { |     gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { | ||||||
|  |  | ||||||
|  | //	if ((unsigned int)ninput_items[0]<(d_vector_length*2)) | ||||||
|  | //	{ | ||||||
|  | //		std::cout<<"End of signal detected\r\n"; | ||||||
|  | //		const int samples_available = ninput_items[0]; | ||||||
|  | //		consume_each(samples_available); | ||||||
|  | //		return 0; | ||||||
|  | //	} | ||||||
|  | 	// process vars | ||||||
|  | 	float code_error_chips=0; | ||||||
|  | 	float correlation_time_s=0; | ||||||
|  | 	float PLL_discriminator_hz=0; | ||||||
|  | 	float carr_nco_hz=0; | ||||||
|  |  | ||||||
|  | 	d_Prompt_prev=d_Prompt; // for the FLL discriminator | ||||||
|  | 	d_Early=gr_complex(0,0); | ||||||
|  | 	d_Prompt=gr_complex(0,0); | ||||||
|  | 	d_Late=gr_complex(0,0); | ||||||
|  |  | ||||||
| 	if (d_enable_tracking==true){ | 	if (d_enable_tracking==true){ | ||||||
| 		/*! | 		/*! | ||||||
| 		 * Receiver signal alignment | 		 * Receiver signal alignment | ||||||
| 		 */ | 		 */ | ||||||
| 	    if (d_pull_in==true) | 	    if (d_pull_in==true) | ||||||
| 	    { | 	    { | ||||||
| 	        int samples_offset=round(d_acq_code_phase_samples); | 	    	int samples_offset; | ||||||
| 	        d_sample_counter+=samples_offset; //count for the processed samples |  | ||||||
|  | 	        // 28/11/2011 ACQ to TRK transition BUG CORRECTION | ||||||
|  | 	        float acq_trk_shif_correction_samples; | ||||||
|  | 	        int acq_to_trk_delay_samples; | ||||||
|  | 	        acq_to_trk_delay_samples=d_sample_counter-d_acq_sample_stamp; | ||||||
|  | 	        acq_trk_shif_correction_samples=d_next_prn_length_samples-fmod((float)acq_to_trk_delay_samples,(float)d_next_prn_length_samples); | ||||||
|  | 	        //std::cout<<"acq_trk_shif_correction="<<acq_trk_shif_correction_samples<<"\r\n"; | ||||||
|  |  | ||||||
|  | 	        samples_offset=round(d_acq_code_phase_samples+acq_trk_shif_correction_samples); | ||||||
|  | 	        // /todo: Check if the sample counter sent to the next block as a time reference should be incremented AFTER sended or BEFORE | ||||||
|  | 	        d_sample_counter_seconds = d_sample_counter_seconds + (((double)samples_offset)/(double)d_fs_in); | ||||||
|  | 	        d_sample_counter=d_sample_counter+samples_offset; //count for the processed samples | ||||||
| 	        d_pull_in=false; | 	        d_pull_in=false; | ||||||
| 	        std::cout<<" samples_offset "<<samples_offset<<"\r\n"; | 	        //std::cout<<" samples_offset="<<samples_offset<<"\r\n"; | ||||||
| 	        consume_each(samples_offset); //shift input to perform alignement with local replica | 	        consume_each(samples_offset); //shift input to perform alignement with local replica | ||||||
| 	        return 1; | 	        return 1; | ||||||
| 	    } | 	    } | ||||||
| 	    // get the sample in and out pointers | 	    // get the sample in and out pointers | ||||||
| 		const gr_complex* in = (gr_complex*) input_items[0]; //block input samples pointer | 		const gr_complex* in = (gr_complex*) input_items[0]; //block input samples pointer | ||||||
| 		float **out = (float **) &output_items[0]; //block output streams pointer | 		double **out = (double **) &output_items[0]; //block output streams pointer | ||||||
|  |  | ||||||
|  | 		// check for samples consistency | ||||||
|  | 		for(int i=0;i<d_current_prn_length_samples;i++) { | ||||||
|  | 			if (std::isnan(in[i].real())==true or std::isnan(in[i].imag())==true)// or std::isinf(in[i].real())==true or std::isinf(in[i].imag())==true) | ||||||
|  | 			{ | ||||||
|  | 				const int samples_available= ninput_items[0]; | ||||||
|  | 				d_sample_counter=d_sample_counter+samples_available; | ||||||
|  | 				LOG_AT_LEVEL(WARNING) << "Detected NaN samples at sample number "<<d_sample_counter; | ||||||
|  | 				consume_each(samples_available); | ||||||
|  | 				return 0; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 		// Update the prn length based on code freq (variable) and | 		// Update the prn length based on code freq (variable) and | ||||||
| 		// sampling frequency (fixed) | 		// sampling frequency (fixed) | ||||||
| 		// variable code PRN sample block size | 		// variable code PRN sample block size | ||||||
| @@ -277,11 +316,6 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto | |||||||
|  |  | ||||||
| 		gr_complex bb_signal_sample(0,0); | 		gr_complex bb_signal_sample(0,0); | ||||||
|  |  | ||||||
| 		d_Prompt_prev=d_Prompt; // for the FLL discriminator |  | ||||||
| 		d_Early=gr_complex(0,0); |  | ||||||
| 		d_Prompt=gr_complex(0,0); |  | ||||||
| 		d_Late=gr_complex(0,0); |  | ||||||
|  |  | ||||||
| 		// perform Early, Prompt and Late correlation | 		// perform Early, Prompt and Late correlation | ||||||
| 		/*! | 		/*! | ||||||
| 		 * \todo Use SIMD-enabled correlators | 		 * \todo Use SIMD-enabled correlators | ||||||
| @@ -299,11 +333,9 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto | |||||||
| 		 * DLL, FLL, and PLL discriminators | 		 * DLL, FLL, and PLL discriminators | ||||||
| 		 */ | 		 */ | ||||||
| 		// Compute DLL error | 		// Compute DLL error | ||||||
| 		float code_error_chips; |  | ||||||
| 		code_error_chips=dll_nc_e_minus_l_normalized(d_Early,d_Late); | 		code_error_chips=dll_nc_e_minus_l_normalized(d_Early,d_Late); | ||||||
|  |  | ||||||
| 		//compute FLL error | 		//compute FLL error | ||||||
| 		float correlation_time_s; |  | ||||||
| 		correlation_time_s=((float)d_current_prn_length_samples)/(float)d_fs_in; | 		correlation_time_s=((float)d_current_prn_length_samples)/(float)d_fs_in; | ||||||
| 		if (d_FLL_wait==1) | 		if (d_FLL_wait==1) | ||||||
| 		{ | 		{ | ||||||
| @@ -316,9 +348,7 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Compute PLL error | 		// Compute PLL error | ||||||
| 		float PLL_discriminator_hz; |  | ||||||
| 		 PLL_discriminator_hz=pll_cloop_two_quadrant_atan(d_Prompt)/(float)TWO_PI; | 		 PLL_discriminator_hz=pll_cloop_two_quadrant_atan(d_Prompt)/(float)TWO_PI; | ||||||
| 		 //PLL_discriminator_hz=pll_four_quadrant_atan(d_Prompt)/(float)TWO_PI; |  | ||||||
|  |  | ||||||
| 		 /*! | 		 /*! | ||||||
| 		  * \todo Update FLL assistance algorithm! | 		  * \todo Update FLL assistance algorithm! | ||||||
| @@ -330,11 +360,13 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto | |||||||
| 		/*! | 		/*! | ||||||
| 		 * DLL and FLL+PLL filter and get current carrier Doppler and code frequency | 		 * DLL and FLL+PLL filter and get current carrier Doppler and code frequency | ||||||
| 		 */ | 		 */ | ||||||
| 		 float carr_nco_hz; |  | ||||||
| 		 carr_nco_hz=d_carrier_loop_filter.get_carrier_error(d_FLL_discriminator_hz,PLL_discriminator_hz,correlation_time_s); | 		 carr_nco_hz=d_carrier_loop_filter.get_carrier_error(d_FLL_discriminator_hz,PLL_discriminator_hz,correlation_time_s); | ||||||
| 		 d_carrier_doppler_hz = (float)d_if_freq + carr_nco_hz; | 		 d_carrier_doppler_hz = (float)d_if_freq + carr_nco_hz; | ||||||
| 		 d_code_freq_hz= GPS_L1_CA_CODE_RATE_HZ- (((d_carrier_doppler_hz - (float)d_if_freq)*GPS_L1_CA_CODE_RATE_HZ)/GPS_L1_FREQ_HZ)-code_error_chips; | 		 d_code_freq_hz= GPS_L1_CA_CODE_RATE_HZ- (((d_carrier_doppler_hz - (float)d_if_freq)*GPS_L1_CA_CODE_RATE_HZ)/GPS_L1_FREQ_HZ)-code_error_chips; | ||||||
|  |  | ||||||
|  | 		/*! | ||||||
|  | 		 * \todo Improve the lock detection algorithm! | ||||||
|  | 		 */ | ||||||
| 		// ####### CN0 ESTIMATION AND LOCK DETECTORS ###### | 		// ####### CN0 ESTIMATION AND LOCK DETECTORS ###### | ||||||
| 		if (d_cn0_estimation_counter<CN0_ESTIMATION_SAMPLES) | 		if (d_cn0_estimation_counter<CN0_ESTIMATION_SAMPLES) | ||||||
| 		{ | 		{ | ||||||
| @@ -347,13 +379,13 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto | |||||||
| 			d_carrier_lock_test=carrier_lock_detector(d_Prompt_buffer,CN0_ESTIMATION_SAMPLES); | 			d_carrier_lock_test=carrier_lock_detector(d_Prompt_buffer,CN0_ESTIMATION_SAMPLES); | ||||||
| 			// ###### TRACKING UNLOCK NOTIFICATION ##### | 			// ###### TRACKING UNLOCK NOTIFICATION ##### | ||||||
| 			int tracking_message; | 			int tracking_message; | ||||||
| 	        if (d_carrier_lock_test<d_carrier_lock_threshold or d_carrier_lock_test>30) | 	        if (d_carrier_lock_test<d_carrier_lock_threshold or d_carrier_lock_test>MINIMUM_VALID_CN0) | ||||||
| 	        { | 	        { | ||||||
| 	             d_carrier_lock_fail_counter++; | 	             d_carrier_lock_fail_counter++; | ||||||
| 	        }else{ | 	        }else{ | ||||||
| 	        	if (d_carrier_lock_fail_counter>0) d_carrier_lock_fail_counter--; | 	        	if (d_carrier_lock_fail_counter>0) d_carrier_lock_fail_counter--; | ||||||
| 	        } | 	        } | ||||||
| 	        if (d_carrier_lock_fail_counter>300) | 	        if (d_carrier_lock_fail_counter>MAXIMUM_LOCK_FAIL_COUNTER) | ||||||
| 	        { | 	        { | ||||||
| 	        	std::cout<<"Channel "<<d_channel << " loss of lock!\r\n"; | 	        	std::cout<<"Channel "<<d_channel << " loss of lock!\r\n"; | ||||||
| 	        	tracking_message=3; //loss of lock | 	        	tracking_message=3; //loss of lock | ||||||
| @@ -365,67 +397,20 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto | |||||||
| 	        //std::cout<<"d_carrier_lock_fail_counter"<<d_carrier_lock_fail_counter<<"\r\n"; | 	        //std::cout<<"d_carrier_lock_fail_counter"<<d_carrier_lock_fail_counter<<"\r\n"; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		/*! | ||||||
|  | 		 * \todo Output the CN0 | ||||||
|  | 		 */ | ||||||
| 		// ########### Output the tracking data to navigation and PVT ########## | 		// ########### Output the tracking data to navigation and PVT ########## | ||||||
| 		// Output channel 1: Prompt correlator output Q | 		// Output channel 0: Prompt correlator output Q | ||||||
| 		*out[0]=d_Early.real(); | 		*out[0]=(double)d_Prompt.real(); | ||||||
| 		// Output channel 2: Prompt correlator output I | 		// Output channel 1: Prompt correlator output I | ||||||
| 		*out[1]=d_Early.imag(); | 		*out[1]=(double)d_Prompt.imag(); | ||||||
| 		// Output channel 3: PRN absolute delay [ms] | 		// Output channel 2: PRN absolute delay [s] | ||||||
| 		*out[2]=(float)(((double)d_sample_counter/(double)d_fs_in)*1000.0); | 		*out[2]=d_sample_counter_seconds; | ||||||
| 		// Output channel 4: PRN code error [ms] | 		// Output channel 3: d_acc_carrier_phase_rad [rad] | ||||||
| 		*out[3]=d_acc_carrier_phase_rad; | 		*out[3]=(double)d_acc_carrier_phase_rad; | ||||||
|  | 		// Output channel 4: PRN code phase [s] | ||||||
| 		if(d_dump) { | 		*out[4]=(double)d_code_phase_samples*(1/(float)d_fs_in); | ||||||
| 			// MULTIPLEXED FILE RECORDING - Record results to file |  | ||||||
| 			float prompt_I; |  | ||||||
| 			float prompt_Q; |  | ||||||
| 			float tmp_E,tmp_P,tmp_L; |  | ||||||
| 			float tmp_float; |  | ||||||
| 			prompt_I=d_Prompt.imag(); |  | ||||||
| 			prompt_Q=d_Prompt.real(); |  | ||||||
| 			tmp_E=std::abs<float>(d_Early); |  | ||||||
| 			tmp_P=std::abs<float>(d_Prompt); |  | ||||||
| 			tmp_L=std::abs<float>(d_Late); |  | ||||||
| 	      	try { |  | ||||||
| 				// EPR |  | ||||||
| 				d_dump_file.write((char*)&tmp_E, sizeof(float)); |  | ||||||
| 				d_dump_file.write((char*)&tmp_P, sizeof(float)); |  | ||||||
| 				d_dump_file.write((char*)&tmp_L, sizeof(float)); |  | ||||||
| 				// PROMPT I and Q (to analyze navigation symbols) |  | ||||||
| 				d_dump_file.write((char*)&prompt_I, sizeof(float)); |  | ||||||
| 				d_dump_file.write((char*)&prompt_Q, sizeof(float)); |  | ||||||
| 				// PRN start sample stamp |  | ||||||
| 				tmp_float=(float)d_sample_counter; |  | ||||||
| 				d_dump_file.write((char*)&tmp_float, sizeof(float)); |  | ||||||
| 				// accumulated carrier phase |  | ||||||
| 				d_dump_file.write((char*)&d_acc_carrier_phase_rad, sizeof(float)); |  | ||||||
|  |  | ||||||
| 				// carrier and code frequency |  | ||||||
| 				d_dump_file.write((char*)&d_carrier_doppler_hz, sizeof(float)); |  | ||||||
| 				d_dump_file.write((char*)&d_code_freq_hz, sizeof(float)); |  | ||||||
|  |  | ||||||
| 				//PLL commands |  | ||||||
| 				d_dump_file.write((char*)&PLL_discriminator_hz, sizeof(float)); |  | ||||||
| 				d_dump_file.write((char*)&carr_nco_hz, sizeof(float)); |  | ||||||
|  |  | ||||||
| 				//DLL commands |  | ||||||
| 				d_dump_file.write((char*)&code_error_chips, sizeof(float)); |  | ||||||
| 				d_dump_file.write((char*)&code_error_chips, sizeof(float)); |  | ||||||
|  |  | ||||||
| 				// CN0 and carrier lock test |  | ||||||
| 				d_dump_file.write((char*)&d_CN0_SNV_dB_Hz, sizeof(float)); |  | ||||||
| 				d_dump_file.write((char*)&d_carrier_lock_test, sizeof(float)); |  | ||||||
|  |  | ||||||
| 				// AUX vars (for debug purposes) |  | ||||||
| 				tmp_float=d_FLL_discriminator_hz; |  | ||||||
| 				d_dump_file.write((char*)&tmp_float, sizeof(float)); |  | ||||||
| 				tmp_float=0.0; |  | ||||||
| 				d_dump_file.write((char*)&tmp_float, sizeof(float)); |  | ||||||
| 	      	 } |  | ||||||
| 			  catch (std::ifstream::failure e) { |  | ||||||
| 				std::cout << "Exception writing trk dump file "<<e.what()<<"\r\n"; |  | ||||||
| 			  } |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// ########## DEBUG OUTPUT | 		// ########## DEBUG OUTPUT | ||||||
| 		/*! | 		/*! | ||||||
| @@ -437,50 +422,115 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto | |||||||
| 			if (floor(d_sample_counter/d_fs_in)!=d_last_seg) | 			if (floor(d_sample_counter/d_fs_in)!=d_last_seg) | ||||||
| 			{ | 			{ | ||||||
| 				d_last_seg=floor(d_sample_counter/d_fs_in); | 				d_last_seg=floor(d_sample_counter/d_fs_in); | ||||||
| 				std::cout<<"t="<<d_last_seg<<std::endl; | 				std::cout<<"Current input signal time="<<d_last_seg<<" [s]"<<std::endl; | ||||||
| 				std::cout<<"TRK CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<< std::endl; | 				std::cout<<"Tracking CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<<" [dB-Hz]"<<std::endl; | ||||||
| 				std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl; | 				//std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl; | ||||||
|  | 				//if (d_last_seg==5) d_carrier_lock_fail_counter=500; //DEBUG: force unlock! | ||||||
| 			} | 			} | ||||||
| 		}else | 		}else | ||||||
| 		{ | 		{ | ||||||
| 			if (floor(d_sample_counter/d_fs_in)!=d_last_seg) | 			if (floor(d_sample_counter/d_fs_in)!=d_last_seg) | ||||||
| 			{ | 			{ | ||||||
| 				d_last_seg=floor(d_sample_counter/d_fs_in); | 				d_last_seg=floor(d_sample_counter/d_fs_in); | ||||||
| 				std::cout<<"TRK CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<< std::endl; | 				std::cout<<"Tracking CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<<" [dB-Hz]"<<std::endl; | ||||||
| 				std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl; | 				//std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		//predict the next loop PRN period length prediction | 		//predict the next loop PRN period length prediction | ||||||
| 		//float T_chip_seconds,T_prn_seconds,T_prn_samples; |  | ||||||
| 		//T_chip_seconds=1/d_code_freq_hz; |  | ||||||
| 		//T_prn_seconds=T_chip_seconds*GPS_L1_CA_CODE_LENGTH_CHIPS-d_rem_code_phase_chips*T_chip_seconds; |  | ||||||
| 		//T_prn_samples=T_prn_seconds*(float)d_fs_in; |  | ||||||
| 		//d_next_prn_length_samples=round(T_prn_samples); |  | ||||||
|  |  | ||||||
| 		float T_chip_seconds; | 		float T_chip_seconds; | ||||||
| 		float T_prn_seconds; | 		float T_prn_seconds; | ||||||
| 		float T_prn_samples; | 		float T_prn_samples; | ||||||
| 		float K_blk_samples; | 		float K_blk_samples; | ||||||
| 		T_chip_seconds=1/d_code_freq_hz; | 		T_chip_seconds=1/d_code_freq_hz; | ||||||
| 		T_prn_seconds=T_chip_seconds*GPS_L1_CA_CODE_LENGTH_CHIPS; | 		T_prn_seconds=T_chip_seconds*GPS_L1_CA_CODE_LENGTH_CHIPS; | ||||||
| 		T_prn_samples=T_prn_seconds*d_fs_in; | 		T_prn_samples=T_prn_seconds*(float)d_fs_in; | ||||||
|  |  | ||||||
| 		d_rem_code_phase_samples=d_next_rem_code_phase_samples; | 		d_rem_code_phase_samples=d_next_rem_code_phase_samples; | ||||||
| 		K_blk_samples=T_prn_samples+d_rem_code_phase_samples; | 		K_blk_samples=T_prn_samples+d_rem_code_phase_samples; | ||||||
| 	    d_next_prn_length_samples=round(K_blk_samples); |  | ||||||
| 	    d_next_rem_code_phase_samples=K_blk_samples-d_next_prn_length_samples; | 		// Update the current PRN delay (code phase in samples) | ||||||
|  | 	    float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS/GPS_L1_CA_CODE_RATE_HZ; | ||||||
|  | 	    float T_prn_true_samples = T_prn_true_seconds*(float)d_fs_in; | ||||||
|  | 	    d_code_phase_samples=d_code_phase_samples+T_prn_samples-T_prn_true_samples; | ||||||
|  | 	    if (d_code_phase_samples<0) | ||||||
|  | 	    { | ||||||
|  | 	    	d_code_phase_samples=T_prn_true_samples+d_code_phase_samples; | ||||||
|  | 	    } | ||||||
|  |  | ||||||
|  | 	    d_code_phase_samples=fmod(d_code_phase_samples,T_prn_true_samples); | ||||||
|  | 	    d_next_prn_length_samples=round(K_blk_samples);//round to a discrete samples | ||||||
|  | 	    d_next_rem_code_phase_samples=K_blk_samples-d_next_prn_length_samples; //rounding error | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	}else{ | ||||||
|  | 		double **out = (double **) &output_items[0]; //block output streams pointer | ||||||
|  | 		*out[0]=0; | ||||||
|  | 		*out[1]=0; | ||||||
|  | 		*out[2]=0; | ||||||
|  | 		*out[3]=0; | ||||||
|  | 		*out[4]=0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	if(d_dump) { | ||||||
|  | 		// MULTIPLEXED FILE RECORDING - Record results to file | ||||||
|  | 		float prompt_I; | ||||||
|  | 		float prompt_Q; | ||||||
|  | 		float tmp_E,tmp_P,tmp_L; | ||||||
|  | 		float tmp_float; | ||||||
|  | 		prompt_I=d_Prompt.imag(); | ||||||
|  | 		prompt_Q=d_Prompt.real(); | ||||||
|  | 		tmp_E=std::abs<float>(d_Early); | ||||||
|  | 		tmp_P=std::abs<float>(d_Prompt); | ||||||
|  | 		tmp_L=std::abs<float>(d_Late); | ||||||
|  |       	try { | ||||||
|  | 			// EPR | ||||||
|  | 			d_dump_file.write((char*)&tmp_E, sizeof(float)); | ||||||
|  | 			d_dump_file.write((char*)&tmp_P, sizeof(float)); | ||||||
|  | 			d_dump_file.write((char*)&tmp_L, sizeof(float)); | ||||||
|  | 			// PROMPT I and Q (to analyze navigation symbols) | ||||||
|  | 			d_dump_file.write((char*)&prompt_I, sizeof(float)); | ||||||
|  | 			d_dump_file.write((char*)&prompt_Q, sizeof(float)); | ||||||
|  | 			// PRN start sample stamp | ||||||
|  | 			//tmp_float=(float)d_sample_counter; | ||||||
|  | 			d_dump_file.write((char*)&d_sample_counter, sizeof(unsigned long int)); | ||||||
|  | 			// accumulated carrier phase | ||||||
|  | 			d_dump_file.write((char*)&d_acc_carrier_phase_rad, sizeof(float)); | ||||||
|  |  | ||||||
|  | 			// carrier and code frequency | ||||||
|  | 			d_dump_file.write((char*)&d_carrier_doppler_hz, sizeof(float)); | ||||||
|  | 			d_dump_file.write((char*)&d_code_freq_hz, sizeof(float)); | ||||||
|  |  | ||||||
|  | 			//PLL commands | ||||||
|  | 			d_dump_file.write((char*)&PLL_discriminator_hz, sizeof(float)); | ||||||
|  | 			d_dump_file.write((char*)&carr_nco_hz, sizeof(float)); | ||||||
|  |  | ||||||
|  | 			//DLL commands | ||||||
|  | 			d_dump_file.write((char*)&code_error_chips, sizeof(float)); | ||||||
|  | 			d_dump_file.write((char*)&d_code_phase_samples, sizeof(float)); | ||||||
|  |  | ||||||
|  | 			// CN0 and carrier lock test | ||||||
|  | 			d_dump_file.write((char*)&d_CN0_SNV_dB_Hz, sizeof(float)); | ||||||
|  | 			d_dump_file.write((char*)&d_carrier_lock_test, sizeof(float)); | ||||||
|  |  | ||||||
|  | 			// AUX vars (for debug purposes) | ||||||
|  | 			tmp_float=0; | ||||||
|  | 			d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||||
|  | 			d_dump_file.write((char*)&d_sample_counter_seconds, sizeof(double)); | ||||||
|  |       	 } | ||||||
|  | 		  catch (std::ifstream::failure e) { | ||||||
|  | 			std::cout << "Exception writing trk dump file "<<e.what()<<"\r\n"; | ||||||
|  | 		  } | ||||||
| 	} | 	} | ||||||
| 	consume_each(d_current_prn_length_samples); // this is necesary in gr_block derivates | 	consume_each(d_current_prn_length_samples); // this is necesary in gr_block derivates | ||||||
|  |     d_sample_counter_seconds = d_sample_counter_seconds + (((double)d_current_prn_length_samples)/(double)d_fs_in); | ||||||
|     d_sample_counter+=d_current_prn_length_samples; //count for the processed samples |     d_sample_counter+=d_current_prn_length_samples; //count for the processed samples | ||||||
| 	return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false | 	return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void gps_l1_ca_dll_fll_pll_tracking_cc::set_acq_code_phase(float code_phase) { | void gps_l1_ca_dll_fll_pll_tracking_cc::set_acq_code_phase(float code_phase) { | ||||||
| 	d_acq_code_phase_samples = code_phase; | 	d_acq_code_phase_samples=code_phase; | ||||||
| 	LOG_AT_LEVEL(INFO) << "Tracking code phase set to " << d_acq_code_phase_samples; | 	LOG_AT_LEVEL(INFO) << "Tracking code phase set to " << d_acq_code_phase_samples; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -497,6 +547,23 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::set_satellite(unsigned int satellite) { | |||||||
| void gps_l1_ca_dll_fll_pll_tracking_cc::set_channel(unsigned int channel) { | void gps_l1_ca_dll_fll_pll_tracking_cc::set_channel(unsigned int channel) { | ||||||
| 	d_channel = channel; | 	d_channel = channel; | ||||||
| 	LOG_AT_LEVEL(INFO) << "Tracking Channel set to " << d_channel; | 	LOG_AT_LEVEL(INFO) << "Tracking Channel set to " << d_channel; | ||||||
|  | 	// ############# ENABLE DATA FILE LOG ################# | ||||||
|  | 	if (d_dump==true) | ||||||
|  | 	{ | ||||||
|  | 		if (d_dump_file.is_open()==false) | ||||||
|  | 		{ | ||||||
|  | 			try { | ||||||
|  | 				d_dump_filename.append(boost::lexical_cast<std::string>(d_channel)); | ||||||
|  | 				d_dump_filename.append(".dat"); | ||||||
|  | 				d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit ); | ||||||
|  | 				d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); | ||||||
|  | 				std::cout<<"Tracking dump enabled on channel "<<d_channel<<" Log file: "<<d_dump_filename.c_str()<<std::endl; | ||||||
|  | 			} | ||||||
|  | 			catch (std::ifstream::failure e) { | ||||||
|  | 				std::cout << "channel "<<d_channel <<" Exception opening trk dump file "<<e.what()<<"\r\n"; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void gps_l1_ca_dll_fll_pll_tracking_cc::set_acq_sample_stamp(unsigned long int sample_stamp) | void gps_l1_ca_dll_fll_pll_tracking_cc::set_acq_sample_stamp(unsigned long int sample_stamp) | ||||||
|   | |||||||
| @@ -62,6 +62,7 @@ gps_l1_ca_dll_fll_pll_make_tracking_cc(unsigned int satellite, | |||||||
| 										unsigned int vector_length, | 										unsigned int vector_length, | ||||||
| 										gr_msg_queue_sptr queue, | 										gr_msg_queue_sptr queue, | ||||||
| 										bool dump, | 										bool dump, | ||||||
|  | 										std::string dump_filename, | ||||||
| 										int order, | 										int order, | ||||||
| 	                                    float fll_bw_hz, | 	                                    float fll_bw_hz, | ||||||
| 	                                    float pll_bw_hz, | 	                                    float pll_bw_hz, | ||||||
| @@ -81,6 +82,7 @@ private: | |||||||
| 										   int vector_length, | 										   int vector_length, | ||||||
| 										   gr_msg_queue_sptr queue, | 										   gr_msg_queue_sptr queue, | ||||||
| 										   bool dump, | 										   bool dump, | ||||||
|  | 										   std::string dump_filename, | ||||||
| 										   int order, | 										   int order, | ||||||
| 										   float fll_bw_hz, | 										   float fll_bw_hz, | ||||||
| 										   float pll_bw_hz, | 										   float pll_bw_hz, | ||||||
| @@ -93,6 +95,7 @@ private: | |||||||
| 									  int vector_length, | 									  int vector_length, | ||||||
| 									  gr_msg_queue_sptr queue, | 									  gr_msg_queue_sptr queue, | ||||||
| 									  bool dump, | 									  bool dump, | ||||||
|  | 									  std::string dump_filename, | ||||||
| 									  int order, | 									  int order, | ||||||
| 									  float fll_bw_hz, | 									  float fll_bw_hz, | ||||||
| 									  float pll_bw_hz, | 									  float pll_bw_hz, | ||||||
| @@ -130,6 +133,7 @@ private: | |||||||
|  |  | ||||||
| 	float d_carrier_doppler_hz; | 	float d_carrier_doppler_hz; | ||||||
| 	float d_code_freq_hz; | 	float d_code_freq_hz; | ||||||
|  | 	float d_code_phase_samples; | ||||||
| 	int d_current_prn_length_samples; | 	int d_current_prn_length_samples; | ||||||
| 	int d_next_prn_length_samples; | 	int d_next_prn_length_samples; | ||||||
| 	int d_FLL_wait; | 	int d_FLL_wait; | ||||||
| @@ -148,6 +152,8 @@ private: | |||||||
|     float d_acc_carrier_phase_rad; |     float d_acc_carrier_phase_rad; | ||||||
|  |  | ||||||
|     unsigned long int d_sample_counter; |     unsigned long int d_sample_counter; | ||||||
|  |     double d_sample_counter_seconds; | ||||||
|  |  | ||||||
|     unsigned long int d_acq_sample_stamp; |     unsigned long int d_acq_sample_stamp; | ||||||
|  |  | ||||||
|     // CN0 estimation and lock detector |     // CN0 estimation and lock detector | ||||||
|   | |||||||
| @@ -55,15 +55,18 @@ | |||||||
|  * \todo Include in definition header file |  * \todo Include in definition header file | ||||||
|  */ |  */ | ||||||
| #define CN0_ESTIMATION_SAMPLES 10 | #define CN0_ESTIMATION_SAMPLES 10 | ||||||
|  | #define MINIMUM_VALID_CN0 25 | ||||||
|  | #define MAXIMUM_LOCK_FAIL_COUNTER 200 | ||||||
|  |  | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
|  |  | ||||||
| gps_l1_ca_dll_pll_tracking_cc_sptr | gps_l1_ca_dll_pll_tracking_cc_sptr | ||||||
| gps_l1_ca_dll_pll_make_tracking_cc(unsigned int satellite, long if_freq, long fs_in, unsigned | gps_l1_ca_dll_pll_make_tracking_cc(unsigned int satellite, long if_freq, long fs_in, unsigned | ||||||
| 			int vector_length, gr_msg_queue_sptr queue, bool dump, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) { | 			int vector_length, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) { | ||||||
|  |  | ||||||
| 	return gps_l1_ca_dll_pll_tracking_cc_sptr(new gps_l1_ca_dll_pll_tracking_cc(satellite, if_freq, | 	return gps_l1_ca_dll_pll_tracking_cc_sptr(new gps_l1_ca_dll_pll_tracking_cc(satellite, if_freq, | ||||||
| 			fs_in, vector_length, queue, dump, pll_bw_hz, dll_bw_hz, early_late_space_chips)); | 			fs_in, vector_length, queue, dump, dump_filename, pll_bw_hz, dll_bw_hz, early_late_space_chips)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void gps_l1_ca_dll_pll_tracking_cc::forecast (int noutput_items, | void gps_l1_ca_dll_pll_tracking_cc::forecast (int noutput_items, | ||||||
| @@ -72,9 +75,9 @@ void gps_l1_ca_dll_pll_tracking_cc::forecast (int noutput_items, | |||||||
| } | } | ||||||
|  |  | ||||||
| gps_l1_ca_dll_pll_tracking_cc::gps_l1_ca_dll_pll_tracking_cc(unsigned int satellite, long if_freq, long fs_in, unsigned | gps_l1_ca_dll_pll_tracking_cc::gps_l1_ca_dll_pll_tracking_cc(unsigned int satellite, long if_freq, long fs_in, unsigned | ||||||
| 		int vector_length, gr_msg_queue_sptr queue, bool dump, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) : | 		int vector_length, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) : | ||||||
| 	    gr_block ("gps_l1_ca_dll_pll_tracking_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)), | 	    gr_block ("gps_l1_ca_dll_pll_tracking_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)), | ||||||
| 	              gr_make_io_signature(5, 5, sizeof(float))) { | 	              gr_make_io_signature(5, 5, sizeof(double))) { | ||||||
|  |  | ||||||
| 		//gr_sync_decimator ("gps_l1_ca_dll_pll_tracking_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)), | 		//gr_sync_decimator ("gps_l1_ca_dll_pll_tracking_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)), | ||||||
| 		//		gr_make_io_signature(3, 3, sizeof(float)),vector_length) { | 		//		gr_make_io_signature(3, 3, sizeof(float)),vector_length) { | ||||||
| @@ -85,8 +88,7 @@ gps_l1_ca_dll_pll_tracking_cc::gps_l1_ca_dll_pll_tracking_cc(unsigned int satell | |||||||
| 	d_if_freq = if_freq; | 	d_if_freq = if_freq; | ||||||
| 	d_fs_in = fs_in; | 	d_fs_in = fs_in; | ||||||
| 	d_vector_length = vector_length; | 	d_vector_length = vector_length; | ||||||
|  | 	d_dump_filename =dump_filename; | ||||||
| 	//std::cout<<"pll_bw_hz= "<<pll_bw_hz<<"dll_bw_hz="<<dll_bw_hz<<"\r\n"; |  | ||||||
|  |  | ||||||
| 	// Initialize tracking  ========================================== | 	// Initialize tracking  ========================================== | ||||||
|  |  | ||||||
| @@ -118,6 +120,7 @@ gps_l1_ca_dll_pll_tracking_cc::gps_l1_ca_dll_pll_tracking_cc(unsigned int satell | |||||||
|  |  | ||||||
|     // sample synchronization |     // sample synchronization | ||||||
|     d_sample_counter=0; |     d_sample_counter=0; | ||||||
|  | 	d_sample_counter_seconds=0; | ||||||
|     d_acq_sample_stamp=0; |     d_acq_sample_stamp=0; | ||||||
|  |  | ||||||
|     d_enable_tracking=false; |     d_enable_tracking=false; | ||||||
| @@ -141,8 +144,9 @@ void gps_l1_ca_dll_pll_tracking_cc::start_tracking(){ | |||||||
| 	 */ | 	 */ | ||||||
| 	unsigned long int acq_trk_diff_samples; | 	unsigned long int acq_trk_diff_samples; | ||||||
| 	float acq_trk_diff_seconds; | 	float acq_trk_diff_seconds; | ||||||
| 	acq_trk_diff_samples=d_sample_counter-d_acq_sample_stamp-d_vector_length; | 	acq_trk_diff_samples=d_sample_counter-d_acq_sample_stamp;//-d_vector_length; | ||||||
| 	acq_trk_diff_seconds=acq_trk_diff_samples/(float)d_fs_in; | 	std::cout<<"acq_trk_diff_samples="<<acq_trk_diff_samples<<"\r\n"; | ||||||
|  | 	acq_trk_diff_seconds=(float)acq_trk_diff_samples/(float)d_fs_in; | ||||||
| 	//doppler effect | 	//doppler effect | ||||||
| 	// Fd=(C/(C+Vr))*F | 	// Fd=(C/(C+Vr))*F | ||||||
| 	float radial_velocity; | 	float radial_velocity; | ||||||
| @@ -155,18 +159,25 @@ void gps_l1_ca_dll_pll_tracking_cc::start_tracking(){ | |||||||
| 	T_chip_mod_seconds=1/d_code_freq_hz; | 	T_chip_mod_seconds=1/d_code_freq_hz; | ||||||
| 	T_prn_mod_seconds=T_chip_mod_seconds*GPS_L1_CA_CODE_LENGTH_CHIPS; | 	T_prn_mod_seconds=T_chip_mod_seconds*GPS_L1_CA_CODE_LENGTH_CHIPS; | ||||||
| 	T_prn_mod_samples=T_prn_mod_seconds*(float)d_fs_in; | 	T_prn_mod_samples=T_prn_mod_seconds*(float)d_fs_in; | ||||||
|  |  | ||||||
|     d_code_phase_step_chips = d_code_freq_hz / (float)d_fs_in; //[chips] |  | ||||||
|     d_next_prn_length_samples=round(T_prn_mod_samples); |     d_next_prn_length_samples=round(T_prn_mod_samples); | ||||||
| 	//compute the code phase chips prediction |  | ||||||
| 	float delta_T_prn_samples; |  | ||||||
| 	float delay_correction_samples; |     float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS/GPS_L1_CA_CODE_RATE_HZ; | ||||||
| 	delta_T_prn_samples=fmod((float)acq_trk_diff_samples,T_prn_mod_samples); |     float T_prn_true_samples = T_prn_true_seconds*(float)d_fs_in; | ||||||
| 	delay_correction_samples=T_prn_mod_samples-delta_T_prn_samples; |     float T_prn_diff_seconds; | ||||||
| 	d_acq_code_phase_samples=d_acq_code_phase_samples-delay_correction_samples; |     T_prn_diff_seconds=T_prn_true_seconds-T_prn_mod_seconds; | ||||||
| 	if (d_acq_code_phase_samples<0){ |     float N_prn_diff; | ||||||
| 		d_acq_code_phase_samples=d_acq_code_phase_samples+T_prn_mod_samples; |     N_prn_diff=acq_trk_diff_seconds/T_prn_true_seconds; | ||||||
| 	} |     float corrected_acq_phase_samples,delay_correction_samples; | ||||||
|  |     corrected_acq_phase_samples=fmod((d_acq_code_phase_samples+T_prn_diff_seconds*N_prn_diff*(float)d_fs_in),T_prn_true_samples); | ||||||
|  |     if (corrected_acq_phase_samples<0) | ||||||
|  |     { | ||||||
|  |     	corrected_acq_phase_samples=T_prn_mod_samples+corrected_acq_phase_samples; | ||||||
|  |     } | ||||||
|  | 	delay_correction_samples=d_acq_code_phase_samples-corrected_acq_phase_samples; | ||||||
|  |  | ||||||
|  | 	d_acq_code_phase_samples=corrected_acq_phase_samples; | ||||||
|  |  | ||||||
| 	d_carrier_doppler_hz=d_acq_carrier_doppler_hz; | 	d_carrier_doppler_hz=d_acq_carrier_doppler_hz; | ||||||
| 	// DLL/PLL filter initialization | 	// DLL/PLL filter initialization | ||||||
| 	d_carrier_loop_filter.initialize(d_carrier_doppler_hz); //initialize the carrier filter | 	d_carrier_loop_filter.initialize(d_carrier_doppler_hz); //initialize the carrier filter | ||||||
| @@ -179,35 +190,23 @@ void gps_l1_ca_dll_pll_tracking_cc::start_tracking(){ | |||||||
|  |  | ||||||
| 	d_carrier_lock_fail_counter=0; | 	d_carrier_lock_fail_counter=0; | ||||||
| 	d_rem_code_phase_samples=0; | 	d_rem_code_phase_samples=0; | ||||||
| 	d_next_rem_code_phase_samples=0; |  | ||||||
| 	d_rem_carr_phase_rad=0; | 	d_rem_carr_phase_rad=0; | ||||||
|  | 	d_rem_code_phase_samples=0; | ||||||
|  | 	d_next_rem_code_phase_samples=0; | ||||||
| 	d_acc_carrier_phase_rad=0; | 	d_acc_carrier_phase_rad=0; | ||||||
|  |  | ||||||
| 	// ############# ENABLE DATA FILE LOG ################# | 	d_code_phase_samples = d_acq_code_phase_samples; | ||||||
| 	if (d_dump==true) |  | ||||||
| 	{ |  | ||||||
| 		if (d_dump_file.is_open()==false) |  | ||||||
| 		{ |  | ||||||
| 			try { |  | ||||||
| 				d_dump_filename="track_ch"; //base path and name for the tracking log file |  | ||||||
| 				d_dump_filename.append(boost::lexical_cast<std::string>(d_channel)); |  | ||||||
| 				d_dump_filename.append(".dat"); |  | ||||||
| 				d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit ); |  | ||||||
| 				d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); |  | ||||||
| 				std::cout<<"Tracking dump enabled on channel "<<d_channel<<" Log file: "<<d_dump_filename.c_str()<<std::endl; |  | ||||||
| 			} |  | ||||||
| 			catch (std::ifstream::failure e) { |  | ||||||
| 				std::cout << "channel "<<d_channel <<" Exception opening trk dump file "<<e.what()<<"\r\n"; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	// DEBUG OUTPUT | 	// DEBUG OUTPUT | ||||||
| 	std::cout<<"Tracking start on channel "<<d_channel<<" for satellite ID* "<< this->d_satellite<< std::endl; | 	std::cout<<"Tracking start on channel "<<d_channel<<" for satellite ID* "<< this->d_satellite<< std::endl; | ||||||
| 	DLOG(INFO) << "Start tracking for satellite "<<this->d_satellite<<" received "; | 	DLOG(INFO) << "Start tracking for satellite "<<this->d_satellite<<" received "; | ||||||
|  |  | ||||||
| 	// enable tracking | 	// enable tracking | ||||||
| 	d_pull_in=true; | 	d_pull_in=true; | ||||||
| 	d_enable_tracking=true; | 	d_enable_tracking=true; | ||||||
| 	std::cout<<"PULL-IN Doppler [Hz]= "<<d_carrier_doppler_hz<<" PULL-IN Code Phase [samples]= "<<d_acq_code_phase_samples<<"\r\n"; |  | ||||||
|  | 	std::cout<<"PULL-IN Doppler [Hz]= "<<d_carrier_doppler_hz<<" Code Phase correction [samples]="<<delay_correction_samples<<" PULL-IN Code Phase [samples]= "<<d_acq_code_phase_samples<<"\r\n"; | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void gps_l1_ca_dll_pll_tracking_cc::update_local_code() | void gps_l1_ca_dll_pll_tracking_cc::update_local_code() | ||||||
| @@ -235,7 +234,7 @@ void gps_l1_ca_dll_pll_tracking_cc::update_local_carrier() | |||||||
| { | { | ||||||
|         float phase_rad, phase_step_rad; |         float phase_rad, phase_step_rad; | ||||||
|  |  | ||||||
|         phase_step_rad = (float)TWO_PI*d_carrier_doppler_hz/d_fs_in; |         phase_step_rad = (float)TWO_PI*d_carrier_doppler_hz/(float)d_fs_in; | ||||||
|         phase_rad=d_rem_carr_phase_rad; |         phase_rad=d_rem_carr_phase_rad; | ||||||
|         for(int i = 0; i < d_current_prn_length_samples; i++) { |         for(int i = 0; i < d_current_prn_length_samples; i++) { | ||||||
|             d_carr_sign[i] = gr_complex(cos(phase_rad),sin(phase_rad)); |             d_carr_sign[i] = gr_complex(cos(phase_rad),sin(phase_rad)); | ||||||
| @@ -247,12 +246,12 @@ void gps_l1_ca_dll_pll_tracking_cc::update_local_carrier() | |||||||
|  |  | ||||||
| gps_l1_ca_dll_pll_tracking_cc::~gps_l1_ca_dll_pll_tracking_cc() { | gps_l1_ca_dll_pll_tracking_cc::~gps_l1_ca_dll_pll_tracking_cc() { | ||||||
| 	d_dump_file.close(); | 	d_dump_file.close(); | ||||||
|     delete d_ca_code; |     delete[] d_ca_code; | ||||||
|     delete d_early_code; |     delete[] d_early_code; | ||||||
|     delete d_prompt_code; |     delete[] d_prompt_code; | ||||||
|     delete d_late_code; |     delete[] d_late_code; | ||||||
|     delete d_carr_sign; |     delete[] d_carr_sign; | ||||||
|     delete d_Prompt_buffer; |     delete[] d_Prompt_buffer; | ||||||
| } | } | ||||||
|  |  | ||||||
| /*! Tracking signal processing | /*! Tracking signal processing | ||||||
| @@ -261,33 +260,71 @@ gps_l1_ca_dll_pll_tracking_cc::~gps_l1_ca_dll_pll_tracking_cc() { | |||||||
|  |  | ||||||
| int gps_l1_ca_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_int &ninput_items, | int gps_l1_ca_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_int &ninput_items, | ||||||
|     gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { |     gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { | ||||||
|  |  | ||||||
|  | //	if ((unsigned int)ninput_items[0]<(d_vector_length*2)) | ||||||
|  | //	{ | ||||||
|  | //		std::cout<<"End of signal detected\r\n"; | ||||||
|  | //		const int samples_available = ninput_items[0]; | ||||||
|  | //		consume_each(samples_available); | ||||||
|  | //		return 0; | ||||||
|  | //	} | ||||||
|  |  | ||||||
|  | 	// process vars | ||||||
|  | 	float carr_error; | ||||||
|  | 	float carr_nco; | ||||||
|  | 	float code_error; | ||||||
|  | 	float code_nco; | ||||||
|  | 	d_Early=gr_complex(0,0); | ||||||
|  | 	d_Prompt=gr_complex(0,0); | ||||||
|  | 	d_Late=gr_complex(0,0); | ||||||
|  |  | ||||||
| 	if (d_enable_tracking==true){ | 	if (d_enable_tracking==true){ | ||||||
|  | 		/*! | ||||||
|  | 		 * Receiver signal alignment | ||||||
|  | 		 */ | ||||||
| 	    if (d_pull_in==true) | 	    if (d_pull_in==true) | ||||||
| 	    { | 	    { | ||||||
| 	        int samples_offset=ceil(d_acq_code_phase_samples); | 	    	int samples_offset; | ||||||
| 	        consume_each(d_acq_code_phase_samples); //shift input to perform alignement with local replica |  | ||||||
| 	        d_sample_counter+=samples_offset; //count for the processed samples | 	        // 28/11/2011 ACQ to TRK transition BUG CORRECTION | ||||||
|  | 	        float acq_trk_shif_correction_samples; | ||||||
|  | 	        int acq_to_trk_delay_samples; | ||||||
|  | 	        acq_to_trk_delay_samples=d_sample_counter-d_acq_sample_stamp; | ||||||
|  | 	        acq_trk_shif_correction_samples=d_next_prn_length_samples-fmod((float)acq_to_trk_delay_samples,(float)d_next_prn_length_samples); | ||||||
|  | 	        //std::cout<<"acq_trk_shif_correction="<<acq_trk_shif_correction_samples<<"\r\n"; | ||||||
|  |  | ||||||
|  | 	        samples_offset=round(d_acq_code_phase_samples+acq_trk_shif_correction_samples); | ||||||
|  | 	        // /todo: Check if the sample counter sent to the next block as a time reference should be incremented AFTER sended or BEFORE | ||||||
|  | 	        d_sample_counter_seconds = d_sample_counter_seconds + (((double)samples_offset)/(double)d_fs_in); | ||||||
|  | 	        d_sample_counter=d_sample_counter+samples_offset; //count for the processed samples | ||||||
| 	        d_pull_in=false; | 	        d_pull_in=false; | ||||||
|  | 	        //std::cout<<" samples_offset="<<samples_offset<<"\r\n"; | ||||||
|  | 	        consume_each(samples_offset); //shift input to perform alignement with local replica | ||||||
| 	        return 1; | 	        return 1; | ||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
| 	    d_current_prn_length_samples=d_next_prn_length_samples; |  | ||||||
|  |  | ||||||
| 		float carr_error; |  | ||||||
| 		float carr_nco; |  | ||||||
| 		float code_error; |  | ||||||
| 		float code_nco; |  | ||||||
|  |  | ||||||
| 		const gr_complex* in = (gr_complex*) input_items[0]; //PRN start block alignement | 		const gr_complex* in = (gr_complex*) input_items[0]; //PRN start block alignement | ||||||
| 		float **out = (float **) &output_items[0]; | 		double **out = (double **) &output_items[0]; | ||||||
|  | 		// check for samples consistency | ||||||
|  | 		for(int i=0;i<d_current_prn_length_samples;i++) { | ||||||
|  | 			if (std::isnan(in[i].real())==true or std::isnan(in[i].imag())==true)// or std::isinf(in[i].real())==true or std::isinf(in[i].imag())==true) | ||||||
|  | 			{ | ||||||
|  | 				const int samples_available= ninput_items[0]; | ||||||
|  | 				d_sample_counter=d_sample_counter+samples_available; | ||||||
|  | 				LOG_AT_LEVEL(WARNING) << "Detected NaN samples at sample number "<<d_sample_counter; | ||||||
|  | 				consume_each(samples_available); | ||||||
|  | 				return 0; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		// Update the prn length based on code freq (variable) and | ||||||
|  | 		// sampling frequency (fixed) | ||||||
|  | 		// variable code PRN sample block size | ||||||
|  | 	    d_current_prn_length_samples=d_next_prn_length_samples; | ||||||
|  |  | ||||||
| 		update_local_code(); | 		update_local_code(); | ||||||
| 		update_local_carrier(); | 		update_local_carrier(); | ||||||
|  |  | ||||||
| 		gr_complex bb_signal_sample(0,0); | 		gr_complex bb_signal_sample(0,0); | ||||||
| 		d_Early=gr_complex(0,0); |  | ||||||
| 		d_Prompt=gr_complex(0,0); |  | ||||||
| 		d_Late=gr_complex(0,0); |  | ||||||
|  |  | ||||||
| 		// perform Early, Prompt and Late correlation | 		// perform Early, Prompt and Late correlation | ||||||
| 		/*! | 		/*! | ||||||
| @@ -328,8 +365,20 @@ int gps_l1_ca_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_in | |||||||
| 		T_prn_samples=T_prn_seconds*d_fs_in; | 		T_prn_samples=T_prn_seconds*d_fs_in; | ||||||
| 		d_rem_code_phase_samples=d_next_rem_code_phase_samples; | 		d_rem_code_phase_samples=d_next_rem_code_phase_samples; | ||||||
| 		K_blk_samples=T_prn_samples+d_rem_code_phase_samples; | 		K_blk_samples=T_prn_samples+d_rem_code_phase_samples; | ||||||
| 	    d_next_prn_length_samples=round(K_blk_samples); |  | ||||||
| 	    d_next_rem_code_phase_samples=K_blk_samples-d_next_prn_length_samples; | 		// Update the current PRN delay (code phase in samples) | ||||||
|  | 	    float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS/GPS_L1_CA_CODE_RATE_HZ; | ||||||
|  | 	    float T_prn_true_samples = T_prn_true_seconds*(float)d_fs_in; | ||||||
|  | 	    d_code_phase_samples=d_code_phase_samples+T_prn_samples-T_prn_true_samples; | ||||||
|  | 	    if (d_code_phase_samples<0) | ||||||
|  | 	    { | ||||||
|  | 	    	d_code_phase_samples=T_prn_true_samples+d_code_phase_samples; | ||||||
|  | 	    } | ||||||
|  |  | ||||||
|  | 	    d_code_phase_samples=fmod(d_code_phase_samples,T_prn_true_samples); | ||||||
|  |  | ||||||
|  | 	    d_next_prn_length_samples=round(K_blk_samples); //round to a discrete samples | ||||||
|  | 	    d_next_rem_code_phase_samples=K_blk_samples-d_next_prn_length_samples; //rounding error | ||||||
|  |  | ||||||
| 		/*! | 		/*! | ||||||
| 		 * \todo Improve the lock detection algorithm! | 		 * \todo Improve the lock detection algorithm! | ||||||
| @@ -345,35 +394,72 @@ int gps_l1_ca_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_in | |||||||
| 			d_CN0_SNV_dB_Hz=gps_l1_ca_CN0_SNV(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES,d_fs_in); | 			d_CN0_SNV_dB_Hz=gps_l1_ca_CN0_SNV(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES,d_fs_in); | ||||||
| 			d_carrier_lock_test=carrier_lock_detector(d_Prompt_buffer,CN0_ESTIMATION_SAMPLES); | 			d_carrier_lock_test=carrier_lock_detector(d_Prompt_buffer,CN0_ESTIMATION_SAMPLES); | ||||||
| 			// ###### TRACKING UNLOCK NOTIFICATION ##### | 			// ###### TRACKING UNLOCK NOTIFICATION ##### | ||||||
|  |  | ||||||
| 			int tracking_message; | 			int tracking_message; | ||||||
| 	        if (d_carrier_lock_test<d_carrier_lock_threshold or d_carrier_lock_test>30) | 	        if (d_carrier_lock_test<d_carrier_lock_threshold or d_carrier_lock_test>MINIMUM_VALID_CN0) | ||||||
| 	        { | 	        { | ||||||
| 	             d_carrier_lock_fail_counter++; | 	             d_carrier_lock_fail_counter++; | ||||||
| 	        }else{ | 	        }else{ | ||||||
| 	        	if (d_carrier_lock_fail_counter>0) d_carrier_lock_fail_counter--; | 	        	if (d_carrier_lock_fail_counter>0) d_carrier_lock_fail_counter--; | ||||||
| 	        } | 	        } | ||||||
| 	        if (d_carrier_lock_fail_counter>200) | 	        if (d_carrier_lock_fail_counter>MAXIMUM_LOCK_FAIL_COUNTER) | ||||||
| 	        { | 	        { | ||||||
| 	        	std::cout<<"Channel "<<d_channel << " loss of lock!\r\n"; | 	        	std::cout<<"Channel "<<d_channel << " loss of lock!\r\n"; | ||||||
| 	        	tracking_message=3; //loss of lock | 	        	tracking_message=3; //loss of lock | ||||||
| 	        	d_channel_internal_queue->push(tracking_message); | 	        	d_channel_internal_queue->push(tracking_message); | ||||||
| 	        	d_carrier_lock_fail_counter=0; | 	        	d_carrier_lock_fail_counter=0; | ||||||
| 	            d_current_prn_length_samples=(int)d_vector_length; //original dsp block length |  | ||||||
| 	        	d_enable_tracking=false; // TODO: check if disabling tracking is consistent with the channel state machine | 	        	d_enable_tracking=false; // TODO: check if disabling tracking is consistent with the channel state machine | ||||||
|  |  | ||||||
| 	        } | 	        } | ||||||
| 	        //std::cout<<"d_carrier_lock_fail_counter"<<d_carrier_lock_fail_counter<<"\r\n"; | 	        //std::cout<<"d_carrier_lock_fail_counter"<<d_carrier_lock_fail_counter<<"\r\n"; | ||||||
| 		} | 		} | ||||||
| 		// Output the tracking data to navigation and PVT |  | ||||||
| 		// Output channel 1: Prompt correlator output Q | 		/*! | ||||||
| 		*out[0]=d_Prompt.real(); | 		 * \todo Output the CN0 | ||||||
| 		// Output channel 2: Prompt correlator output I | 		 */ | ||||||
| 		*out[1]=d_Prompt.imag(); | 		// ########### Output the tracking data to navigation and PVT ########## | ||||||
| 		// Output channel 3: Current tracking time [ms] | 		// Output channel 0: Prompt correlator output Q | ||||||
| 		*out[2]=(float)(((double)d_sample_counter/(double)d_fs_in)*1000.0); | 		*out[0]=(double)d_Prompt.real(); | ||||||
| 		// Output channel 4: Carrier accumulated phase | 		// Output channel 1: Prompt correlator output I | ||||||
| 		*out[3]=d_acc_carrier_phase_rad; | 		*out[1]=(double)d_Prompt.imag(); | ||||||
|  | 		// Output channel 2: PRN absolute delay [s] | ||||||
|  | 		*out[2]=d_sample_counter_seconds; | ||||||
|  | 		// Output channel 3: d_acc_carrier_phase_rad [rad] | ||||||
|  | 		*out[3]=(double)d_acc_carrier_phase_rad; | ||||||
|  | 		// Output channel 4: PRN code phase [s] | ||||||
|  | 		*out[4]=(double)d_code_phase_samples*(1/(float)d_fs_in); | ||||||
|  |  | ||||||
|  | 		// ########## DEBUG OUTPUT | ||||||
|  | 		/*! | ||||||
|  | 		 *  \todo The stop timer has to be moved to the signal source! | ||||||
|  | 		 */ | ||||||
|  | 		// debug: Second counter in channel 0 | ||||||
|  | 		if (d_channel==0) | ||||||
|  | 		{ | ||||||
|  | 			if (floor(d_sample_counter/d_fs_in)!=d_last_seg) | ||||||
|  | 			{ | ||||||
|  | 				d_last_seg=floor(d_sample_counter/d_fs_in); | ||||||
|  | 				std::cout<<"Current input signal time="<<d_last_seg<<" [s]"<<std::endl; | ||||||
|  | 				std::cout<<"Tracking CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<<" [dB-Hz]"<<std::endl; | ||||||
|  | 				//std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl; | ||||||
|  | 				//if (d_last_seg==5) d_carrier_lock_fail_counter=500; //DEBUG: force unlock! | ||||||
|  | 			} | ||||||
|  | 		}else | ||||||
|  | 		{ | ||||||
|  | 			if (floor(d_sample_counter/d_fs_in)!=d_last_seg) | ||||||
|  | 			{ | ||||||
|  | 				d_last_seg=floor(d_sample_counter/d_fs_in); | ||||||
|  | 				std::cout<<"Tracking CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<<" [dB-Hz]"<<std::endl; | ||||||
|  | 				//std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}else{ | ||||||
|  | 		double **out = (double **) &output_items[0]; //block output streams pointer | ||||||
|  | 		*out[0]=0; | ||||||
|  | 		*out[1]=0; | ||||||
|  | 		*out[2]=0; | ||||||
|  | 		*out[3]=0; | ||||||
|  | 		*out[4]=0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 		if(d_dump) { | 		if(d_dump) { | ||||||
| 			// MULTIPLEXED FILE RECORDING - Record results to file | 			// MULTIPLEXED FILE RECORDING - Record results to file | ||||||
| @@ -395,8 +481,8 @@ int gps_l1_ca_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_in | |||||||
| 				d_dump_file.write((char*)&prompt_I, sizeof(float)); | 				d_dump_file.write((char*)&prompt_I, sizeof(float)); | ||||||
| 				d_dump_file.write((char*)&prompt_Q, sizeof(float)); | 				d_dump_file.write((char*)&prompt_Q, sizeof(float)); | ||||||
| 				// PRN start sample stamp | 				// PRN start sample stamp | ||||||
| 				tmp_float=(float)d_sample_counter; | 				//tmp_float=(float)d_sample_counter; | ||||||
| 				d_dump_file.write((char*)&tmp_float, sizeof(float)); | 				d_dump_file.write((char*)&d_sample_counter, sizeof(unsigned long int)); | ||||||
| 				// accumulated carrier phase | 				// accumulated carrier phase | ||||||
| 				d_dump_file.write((char*)&d_acc_carrier_phase_rad, sizeof(float)); | 				d_dump_file.write((char*)&d_acc_carrier_phase_rad, sizeof(float)); | ||||||
|  |  | ||||||
| @@ -417,38 +503,18 @@ int gps_l1_ca_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_in | |||||||
| 				d_dump_file.write((char*)&d_carrier_lock_test, sizeof(float)); | 				d_dump_file.write((char*)&d_carrier_lock_test, sizeof(float)); | ||||||
|  |  | ||||||
| 				// AUX vars (for debug purposes) | 				// AUX vars (for debug purposes) | ||||||
| 				tmp_float=0.0; | 				tmp_float=0; | ||||||
| 				d_dump_file.write((char*)&tmp_float, sizeof(float)); |  | ||||||
| 				tmp_float=0.0; |  | ||||||
| 				d_dump_file.write((char*)&tmp_float, sizeof(float)); | 				d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||||
|  | 				d_dump_file.write((char*)&d_sample_counter_seconds, sizeof(double)); | ||||||
| 	      	 } | 	      	 } | ||||||
| 			  catch (std::ifstream::failure e) { | 			  catch (std::ifstream::failure e) { | ||||||
| 				std::cout << "Exception writing trk dump file "<<e.what()<<"\r\n"; | 				std::cout << "Exception writing trk dump file "<<e.what()<<"\r\n"; | ||||||
| 			  } | 			  } | ||||||
| 		} | 		} | ||||||
| 		// ########## DEBUG OUTPUT |  | ||||||
| 		// debug: Second counter in channel 0 |  | ||||||
| 		if (d_channel==0) |  | ||||||
| 		{ |  | ||||||
| 			if (floor(d_sample_counter/d_fs_in)!=d_last_seg) |  | ||||||
| 			{ |  | ||||||
| 				d_last_seg=floor(d_sample_counter/d_fs_in); |  | ||||||
| 				std::cout<<"t="<<d_last_seg<<std::endl; |  | ||||||
| 				std::cout<<"TRK CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<< std::endl; |  | ||||||
| 				std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl; |  | ||||||
| 			} |  | ||||||
| 		}else |  | ||||||
| 		{ |  | ||||||
| 			if (floor(d_sample_counter/d_fs_in)!=d_last_seg) |  | ||||||
| 			{ |  | ||||||
| 				d_last_seg=floor(d_sample_counter/d_fs_in); |  | ||||||
| 				std::cout<<"TRK CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<< std::endl; |  | ||||||
| 				std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	consume_each(d_current_prn_length_samples); // this is necesary in gr_block derivates | 	consume_each(d_current_prn_length_samples); // this is necesary in gr_block derivates | ||||||
|         d_sample_counter+=d_current_prn_length_samples; //count for the processed samples |     d_sample_counter_seconds = d_sample_counter_seconds + (((double)d_current_prn_length_samples)/(double)d_fs_in); | ||||||
|  |     d_sample_counter+=d_current_prn_length_samples; //count for the processed samples | ||||||
| 	return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false | 	return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -470,6 +536,23 @@ void gps_l1_ca_dll_pll_tracking_cc::set_satellite(unsigned int satellite) { | |||||||
| void gps_l1_ca_dll_pll_tracking_cc::set_channel(unsigned int channel) { | void gps_l1_ca_dll_pll_tracking_cc::set_channel(unsigned int channel) { | ||||||
| 	d_channel = channel; | 	d_channel = channel; | ||||||
| 	LOG_AT_LEVEL(INFO) << "Tracking Channel set to " << d_channel; | 	LOG_AT_LEVEL(INFO) << "Tracking Channel set to " << d_channel; | ||||||
|  | 	// ############# ENABLE DATA FILE LOG ################# | ||||||
|  | 	if (d_dump==true) | ||||||
|  | 	{ | ||||||
|  | 		if (d_dump_file.is_open()==false) | ||||||
|  | 		{ | ||||||
|  | 			try { | ||||||
|  | 				d_dump_filename.append(boost::lexical_cast<std::string>(d_channel)); | ||||||
|  | 				d_dump_filename.append(".dat"); | ||||||
|  | 				d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit ); | ||||||
|  | 				d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); | ||||||
|  | 				std::cout<<"Tracking dump enabled on channel "<<d_channel<<" Log file: "<<d_dump_filename.c_str()<<std::endl; | ||||||
|  | 			} | ||||||
|  | 			catch (std::ifstream::failure e) { | ||||||
|  | 				std::cout << "channel "<<d_channel <<" Exception opening trk dump file "<<e.what()<<"\r\n"; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void gps_l1_ca_dll_pll_tracking_cc::set_acq_sample_stamp(unsigned long int sample_stamp) | void gps_l1_ca_dll_pll_tracking_cc::set_acq_sample_stamp(unsigned long int sample_stamp) | ||||||
|   | |||||||
| @@ -42,8 +42,8 @@ | |||||||
| //#include <gnuradio/gr_sync_decimator.h> | //#include <gnuradio/gr_sync_decimator.h> | ||||||
|  |  | ||||||
| #include "gps_sdr_signal_processing.h" | #include "gps_sdr_signal_processing.h" | ||||||
| #include "tracking_2rd_DLL_filter.h" | #include "tracking_2nd_DLL_filter.h" | ||||||
| #include "tracking_2rd_PLL_filter.h" | #include "tracking_2nd_PLL_filter.h" | ||||||
|  |  | ||||||
| #include <queue> | #include <queue> | ||||||
| #include <boost/thread/mutex.hpp> | #include <boost/thread/mutex.hpp> | ||||||
| @@ -60,6 +60,7 @@ gps_l1_ca_dll_pll_make_tracking_cc(unsigned int satellite, long if_freq, | |||||||
|                                    int vector_length, |                                    int vector_length, | ||||||
|                                    gr_msg_queue_sptr queue, |                                    gr_msg_queue_sptr queue, | ||||||
|                                    bool dump, |                                    bool dump, | ||||||
|  |                                    std::string dump_filename, | ||||||
|                                    float pll_bw_hz, |                                    float pll_bw_hz, | ||||||
|                                    float dll_bw_hz, |                                    float dll_bw_hz, | ||||||
|                                    float early_late_space_chips); |                                    float early_late_space_chips); | ||||||
| @@ -76,6 +77,7 @@ private: | |||||||
|                                        int vector_length, |                                        int vector_length, | ||||||
|                                        gr_msg_queue_sptr queue, |                                        gr_msg_queue_sptr queue, | ||||||
|                                        bool dump, |                                        bool dump, | ||||||
|  |                                        std::string dump_filename, | ||||||
|                                        float pll_bw_hz, |                                        float pll_bw_hz, | ||||||
|                                        float dll_bw_hz, |                                        float dll_bw_hz, | ||||||
|                                        float early_late_space_chips); |                                        float early_late_space_chips); | ||||||
| @@ -85,6 +87,7 @@ private: | |||||||
|                                   int vector_length, |                                   int vector_length, | ||||||
|                                   gr_msg_queue_sptr queue, |                                   gr_msg_queue_sptr queue, | ||||||
|                                   bool dump, |                                   bool dump, | ||||||
|  |                                   std::string dump_filename, | ||||||
|                                   float pll_bw_hz, |                                   float pll_bw_hz, | ||||||
|                                   float dll_bw_hz, |                                   float dll_bw_hz, | ||||||
|                                   float early_late_space_chips); |                                   float early_late_space_chips); | ||||||
| @@ -123,8 +126,8 @@ private: | |||||||
|     float d_rem_carr_phase_rad; |     float d_rem_carr_phase_rad; | ||||||
|  |  | ||||||
|     // PLL and DLL filter library |     // PLL and DLL filter library | ||||||
|     tracking_2rd_DLL_filter d_code_loop_filter; |     tracking_2nd_DLL_filter d_code_loop_filter; | ||||||
|     tracking_2rd_PLL_filter d_carrier_loop_filter; |     tracking_2nd_PLL_filter d_carrier_loop_filter; | ||||||
|  |  | ||||||
|     // acquisition |     // acquisition | ||||||
|     float d_acq_code_phase_samples; |     float d_acq_code_phase_samples; | ||||||
| @@ -134,10 +137,12 @@ private: | |||||||
|     float d_code_freq_hz; |     float d_code_freq_hz; | ||||||
|     float d_carrier_doppler_hz; |     float d_carrier_doppler_hz; | ||||||
|     float d_acc_carrier_phase_rad; |     float d_acc_carrier_phase_rad; | ||||||
|  |     float d_code_phase_samples; | ||||||
|  |  | ||||||
|     //PRN period in samples |     //PRN period in samples | ||||||
| 	int d_current_prn_length_samples; | 	int d_current_prn_length_samples; | ||||||
| 	int d_next_prn_length_samples; | 	int d_next_prn_length_samples; | ||||||
|  | 	double d_sample_counter_seconds; | ||||||
|  |  | ||||||
| 	//processing samples counters | 	//processing samples counters | ||||||
|     unsigned long int d_sample_counter; |     unsigned long int d_sample_counter; | ||||||
|   | |||||||
| @@ -3,5 +3,5 @@ project : build-dir ../../../../build ; | |||||||
| obj tracking_discriminators : tracking_discriminators.cc ; | obj tracking_discriminators : tracking_discriminators.cc ; | ||||||
| obj CN_estimators : CN_estimators.cc ; | obj CN_estimators : CN_estimators.cc ; | ||||||
| obj tracking_FLL_PLL_filter	: tracking_FLL_PLL_filter.cc ; | obj tracking_FLL_PLL_filter	: tracking_FLL_PLL_filter.cc ; | ||||||
| obj tracking_2rd_PLL_filter	: tracking_2rd_PLL_filter.cc ; | obj tracking_2nd_PLL_filter	: tracking_2nd_PLL_filter.cc ; | ||||||
| obj tracking_2rd_DLL_filter	: tracking_2rd_DLL_filter.cc ; | obj tracking_2nd_DLL_filter	: tracking_2nd_DLL_filter.cc ; | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| /*!
 | /*!
 | ||||||
|  * \file tracking_2rd_DLL_filter.cc |  * \file tracking_2nd_DLL_filter.cc | ||||||
|  * \brief Class that implements 2 order DLL filter for code tracking loop. |  * \brief Class that implements 2 order DLL filter for code tracking loop. | ||||||
|  * \author Javier Arribas, 2011. jarribas(at)cttc.es |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  * |  * | ||||||
| @@ -34,10 +34,10 @@ | |||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #include "tracking_2rd_DLL_filter.h" | #include "tracking_2nd_DLL_filter.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void tracking_2rd_DLL_filter::calculate_lopp_coef(float* tau1,float* tau2, float lbw, float zeta, float k){ | void tracking_2nd_DLL_filter::calculate_lopp_coef(float* tau1,float* tau2, float lbw, float zeta, float k){ | ||||||
| 	// Solve natural frequency
 | 	// Solve natural frequency
 | ||||||
| 	float Wn; | 	float Wn; | ||||||
| 	Wn = lbw*8*zeta / (4*zeta*zeta + 1); | 	Wn = lbw*8*zeta / (4*zeta*zeta + 1); | ||||||
| @@ -46,13 +46,13 @@ void tracking_2rd_DLL_filter::calculate_lopp_coef(float* tau1,float* tau2, float | |||||||
| 	*tau2 = (2.0 * zeta) / Wn; | 	*tau2 = (2.0 * zeta) / Wn; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void tracking_2rd_DLL_filter::set_DLL_BW(float dll_bw_hz) | void tracking_2nd_DLL_filter::set_DLL_BW(float dll_bw_hz) | ||||||
| { | { | ||||||
| 	//Calculate filter coefficient values
 | 	//Calculate filter coefficient values
 | ||||||
| 	d_dllnoisebandwidth=dll_bw_hz; | 	d_dllnoisebandwidth=dll_bw_hz; | ||||||
| 	calculate_lopp_coef(&d_tau1_code, &d_tau2_code, d_dllnoisebandwidth, d_dlldampingratio,1.0);// Calculate filter coefficient values
 | 	calculate_lopp_coef(&d_tau1_code, &d_tau2_code, d_dllnoisebandwidth, d_dlldampingratio,1.0);// Calculate filter coefficient values
 | ||||||
| } | } | ||||||
| void tracking_2rd_DLL_filter::initialize(float d_acq_code_phase_samples) | void tracking_2nd_DLL_filter::initialize(float d_acq_code_phase_samples) | ||||||
| { | { | ||||||
|     // code tracking loop parameters
 |     // code tracking loop parameters
 | ||||||
|     d_old_code_nco   = 0.0; |     d_old_code_nco   = 0.0; | ||||||
| @@ -60,7 +60,7 @@ void tracking_2rd_DLL_filter::initialize(float d_acq_code_phase_samples) | |||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float tracking_2rd_DLL_filter::get_code_nco(float DLL_discriminator) | float tracking_2nd_DLL_filter::get_code_nco(float DLL_discriminator) | ||||||
| { | { | ||||||
| 	float code_nco; | 	float code_nco; | ||||||
| 	code_nco = d_old_code_nco + (d_tau2_code/d_tau1_code)*(DLL_discriminator - d_old_code_error) + DLL_discriminator * (d_pdi_code/d_tau1_code); | 	code_nco = d_old_code_nco + (d_tau2_code/d_tau1_code)*(DLL_discriminator - d_old_code_error) + DLL_discriminator * (d_pdi_code/d_tau1_code); | ||||||
| @@ -69,13 +69,13 @@ float tracking_2rd_DLL_filter::get_code_nco(float DLL_discriminator) | |||||||
| 	return code_nco; | 	return code_nco; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| tracking_2rd_DLL_filter::tracking_2rd_DLL_filter () | tracking_2nd_DLL_filter::tracking_2nd_DLL_filter () | ||||||
| { | { | ||||||
| 	d_pdi_code = 0.001;// Summation interval for code
 | 	d_pdi_code = 0.001;// Summation interval for code
 | ||||||
| 	d_dlldampingratio=0.7; | 	d_dlldampingratio=0.7; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| tracking_2rd_DLL_filter::~tracking_2rd_DLL_filter () | tracking_2nd_DLL_filter::~tracking_2nd_DLL_filter () | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| /*!
 | /*!
 | ||||||
|  * \file tracking_2rd_DLL_filter.h |  * \file tracking_2nd_DLL_filter.h | ||||||
|  * \brief Class that implements 2 order DLL filter for code tracking loop. |  * \brief Class that implements 2 order DLL filter for code tracking loop. | ||||||
|  * \author Javier Arribas, 2011. jarribas(at)cttc.es |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  * |  * | ||||||
| @@ -33,10 +33,10 @@ | |||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #ifndef TRACKING_2RD_DLL_FILTER_H_ | #ifndef TRACKING_2ND_DLL_FILTER_H_ | ||||||
| #define TRACKING_2RD_DLL_FILTER_H_ | #define TRACKING_2ND_DLL_FILTER_H_ | ||||||
| 
 | 
 | ||||||
| class tracking_2rd_DLL_filter | class tracking_2nd_DLL_filter | ||||||
| { | { | ||||||
| private: | private: | ||||||
|     // PLL filter parameters
 |     // PLL filter parameters
 | ||||||
| @@ -54,8 +54,8 @@ public: | |||||||
| 	void set_DLL_BW(float dll_bw_hz); | 	void set_DLL_BW(float dll_bw_hz); | ||||||
| 	void initialize(float d_acq_code_phase_samples); | 	void initialize(float d_acq_code_phase_samples); | ||||||
| 	float get_code_nco(float DLL_discriminator); | 	float get_code_nco(float DLL_discriminator); | ||||||
| 	tracking_2rd_DLL_filter(); | 	tracking_2nd_DLL_filter(); | ||||||
| 	~tracking_2rd_DLL_filter(); | 	~tracking_2nd_DLL_filter(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| /*!
 | /*!
 | ||||||
|  * \file tracking_2rd_PLL_filter.cc |  * \file tracking_2nd_PLL_filter.cc | ||||||
|  * \brief Class that implements 2 order PLL filter for tracking carrier loop. |  * \brief Class that implements 2 order PLL filter for tracking carrier loop. | ||||||
|  * \author Javier Arribas, 2011. jarribas(at)cttc.es |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  * |  * | ||||||
| @@ -33,10 +33,10 @@ | |||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include "tracking_2rd_PLL_filter.h" | #include "tracking_2nd_PLL_filter.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void tracking_2rd_PLL_filter::calculate_lopp_coef(float* tau1,float* tau2, float lbw, float zeta, float k){ | void tracking_2nd_PLL_filter::calculate_lopp_coef(float* tau1,float* tau2, float lbw, float zeta, float k){ | ||||||
| 	// Solve natural frequency
 | 	// Solve natural frequency
 | ||||||
| 	float Wn; | 	float Wn; | ||||||
| 	Wn = lbw*8*zeta / (4*zeta*zeta + 1); | 	Wn = lbw*8*zeta / (4*zeta*zeta + 1); | ||||||
| @@ -45,20 +45,20 @@ void tracking_2rd_PLL_filter::calculate_lopp_coef(float* tau1,float* tau2, float | |||||||
| 	*tau2 = (2.0 * zeta) / Wn; | 	*tau2 = (2.0 * zeta) / Wn; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void tracking_2rd_PLL_filter::set_PLL_BW(float pll_bw_hz) | void tracking_2nd_PLL_filter::set_PLL_BW(float pll_bw_hz) | ||||||
| { | { | ||||||
| 	//Calculate filter coefficient values
 | 	//Calculate filter coefficient values
 | ||||||
| 	d_pllnoisebandwidth=pll_bw_hz; | 	d_pllnoisebandwidth=pll_bw_hz; | ||||||
| 	calculate_lopp_coef(&d_tau1_carr, &d_tau2_carr, d_pllnoisebandwidth, d_plldampingratio,0.25);// Calculate filter coefficient values
 | 	calculate_lopp_coef(&d_tau1_carr, &d_tau2_carr, d_pllnoisebandwidth, d_plldampingratio,0.25);// Calculate filter coefficient values
 | ||||||
| } | } | ||||||
| void tracking_2rd_PLL_filter::initialize(float d_acq_carrier_doppler_hz) | void tracking_2nd_PLL_filter::initialize(float d_acq_carrier_doppler_hz) | ||||||
| { | { | ||||||
|     // carrier/Costas loop parameters
 |     // carrier/Costas loop parameters
 | ||||||
|     d_old_carr_nco   = 0.0; |     d_old_carr_nco   = 0.0; | ||||||
|     d_old_carr_error = 0.0; |     d_old_carr_error = 0.0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float tracking_2rd_PLL_filter::get_carrier_nco(float PLL_discriminator) | float tracking_2nd_PLL_filter::get_carrier_nco(float PLL_discriminator) | ||||||
| { | { | ||||||
| 	float carr_nco; | 	float carr_nco; | ||||||
| 	carr_nco = d_old_carr_nco+(d_tau2_carr/d_tau1_carr)*(PLL_discriminator - d_old_carr_error) + PLL_discriminator * (d_pdi_carr/d_tau1_carr); | 	carr_nco = d_old_carr_nco+(d_tau2_carr/d_tau1_carr)*(PLL_discriminator - d_old_carr_error) + PLL_discriminator * (d_pdi_carr/d_tau1_carr); | ||||||
| @@ -67,14 +67,14 @@ float tracking_2rd_PLL_filter::get_carrier_nco(float PLL_discriminator) | |||||||
| 	return carr_nco; | 	return carr_nco; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| tracking_2rd_PLL_filter::tracking_2rd_PLL_filter () | tracking_2nd_PLL_filter::tracking_2nd_PLL_filter () | ||||||
| { | { | ||||||
| 	//--- PLL variables --------------------------------------------------------
 | 	//--- PLL variables --------------------------------------------------------
 | ||||||
| 	d_pdi_carr = 0.001;// Summation interval for carrier
 | 	d_pdi_carr = 0.001;// Summation interval for carrier
 | ||||||
| 	d_plldampingratio=0.65; | 	d_plldampingratio=0.65; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| tracking_2rd_PLL_filter::~tracking_2rd_PLL_filter () | tracking_2nd_PLL_filter::~tracking_2nd_PLL_filter () | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| /*!
 | /*!
 | ||||||
|  * \file tracking_2rd_PLL_filter.h |  * \file tracking_2nd_PLL_filter.h | ||||||
|  * \brief Class that implements 2 order PLL filter for tracking carrier loop |  * \brief Class that implements 2 order PLL filter for tracking carrier loop | ||||||
|  * \author Javier Arribas, 2011. jarribas(at)cttc.es |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  * |  * | ||||||
| @@ -33,10 +33,10 @@ | |||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #ifndef TRACKING_2RD_PLL_FILTER_H_ | #ifndef TRACKING_2ND_PLL_FILTER_H_ | ||||||
| #define TRACKING_2RD_PLL_FILTER_H_ | #define TRACKING_2ND_PLL_FILTER_H_ | ||||||
| 
 | 
 | ||||||
| class tracking_2rd_PLL_filter | class tracking_2nd_PLL_filter | ||||||
| { | { | ||||||
| private: | private: | ||||||
|     // PLL filter parameters
 |     // PLL filter parameters
 | ||||||
| @@ -55,8 +55,8 @@ public: | |||||||
| 	void set_PLL_BW(float pll_bw_hz); | 	void set_PLL_BW(float pll_bw_hz); | ||||||
| 	void initialize(float d_acq_carrier_doppler_hz); | 	void initialize(float d_acq_carrier_doppler_hz); | ||||||
| 	float get_carrier_nco(float PLL_discriminator); | 	float get_carrier_nco(float PLL_discriminator); | ||||||
| 	tracking_2rd_PLL_filter(); | 	tracking_2nd_PLL_filter(); | ||||||
| 	~tracking_2rd_PLL_filter(); | 	~tracking_2nd_PLL_filter(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
| @@ -76,7 +76,6 @@ void tracking_FLL_PLL_filter::initialize(float d_acq_carrier_doppler_hz) | |||||||
| 		d_pll_w 		= d_acq_carrier_doppler_hz; | 		d_pll_w 		= d_acq_carrier_doppler_hz; | ||||||
| 		d_pll_x 		= 0; | 		d_pll_x 		= 0; | ||||||
| 	} | 	} | ||||||
| 	std::cout<<" d_pll_x init = "<<d_pll_x<<"\r\n"; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| float tracking_FLL_PLL_filter::get_carrier_error(float FLL_discriminator, float PLL_discriminator, float correlation_time_s) | float tracking_FLL_PLL_filter::get_carrier_error(float FLL_discriminator, float PLL_discriminator, float correlation_time_s) | ||||||
|   | |||||||
							
								
								
									
										59
									
								
								src/core/interfaces/pvt_interface.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/core/interfaces/pvt_interface.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | /*! | ||||||
|  |  * \file pvt_interface.h | ||||||
|  |  * \brief This class represents an interface to a PVT gnss block. | ||||||
|  |  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  |  * | ||||||
|  |  * Abstract class for pseudorange_intefaces. Since all its methods are virtual, | ||||||
|  |  * this class cannot be instantiated directly, and a subclass can only be | ||||||
|  |  * instantiated directly if all inherited pure virtual methods have been | ||||||
|  |  * implemented by that class or a parent class. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifndef GNSS_SDR_PVT_INTERFACE_H_ | ||||||
|  | #define GNSS_SDR_PVT_INTERFACE_H_ | ||||||
|  |  | ||||||
|  | #include "gnss_block_interface.h" | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \brief This class represents an interface to a PVT gnss block. | ||||||
|  |  * | ||||||
|  |  * Abstract class for PVT intefaces, derived from GNSSBlockInterface. | ||||||
|  |  * Since all its methods are virtual, | ||||||
|  |  * this class cannot be instantiated directly, and a subclass can only be | ||||||
|  |  * instantiated directly if all inherited pure virtual methods have been | ||||||
|  |  * implemented by that class or a parent class. | ||||||
|  |  */ | ||||||
|  | class PvtInterface : public GNSSBlockInterface | ||||||
|  | { | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |  | ||||||
|  |     virtual void reset() = 0; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif /* GNSS_SDR_PVT_INTERFACE_H_ */ | ||||||
| @@ -47,7 +47,7 @@ | |||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
|  |  | ||||||
| DEFINE_string(config_file, "../conf/mercurio.conf", | DEFINE_string(config_file, "../conf/gnss-sdr.conf", | ||||||
|         "Path to the file containing the configuration parameters") |         "Path to the file containing the configuration parameters") | ||||||
| ; | ; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -76,7 +76,7 @@ std::string FileConfiguration::property(std::string property_name, std::string d | |||||||
|         } |         } | ||||||
|     else |     else | ||||||
|         { |         { | ||||||
|             return ini_reader_->Get("mercurio", property_name, default_value); |             return ini_reader_->Get("GNSS-SDR", property_name, default_value); | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
|  * \brief  This class implements a factory that returns instances of GNSS blocks. |  * \brief  This class implements a factory that returns instances of GNSS blocks. | ||||||
|  * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com |  * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com | ||||||
|  *         Luis Esteve, 2011. luis(at)epsilon-formacion.com |  *         Luis Esteve, 2011. luis(at)epsilon-formacion.com | ||||||
|  |  *         Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  * |  * | ||||||
|  * This class encapsulates the complexity behind the instantiation |  * This class encapsulates the complexity behind the instantiation | ||||||
|  * of GNSS blocks. |  * of GNSS blocks. | ||||||
| @@ -58,6 +59,7 @@ | |||||||
| #include "gps_l1_ca_dll_fll_pll_tracking.h" | #include "gps_l1_ca_dll_fll_pll_tracking.h" | ||||||
| #include "gps_l1_ca_telemetry_decoder.h" | #include "gps_l1_ca_telemetry_decoder.h" | ||||||
| #include "gps_l1_ca_observables.h" | #include "gps_l1_ca_observables.h" | ||||||
|  | #include "gps_l1_ca_pvt.h" | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
|  |  | ||||||
| @@ -195,9 +197,9 @@ std::vector<GNSSBlockInterface*>* GNSSBlockFactory::GetChannels( | |||||||
|         channels->push_back(GetChannel(configuration, |         channels->push_back(GetChannel(configuration, | ||||||
|                 acquisition_implementation, tracking, telemetry_decoder, i, |                 acquisition_implementation, tracking, telemetry_decoder, i, | ||||||
|                 queue)); |                 queue)); | ||||||
|         std::cout << "getchannel_" << i << ", acq_implementation_name: " |         //std::cout << "getchannel_" << i << ", acq_implementation_name: " | ||||||
|                 << acquisition_implementation_name << ", implementation: " |                 //<< acquisition_implementation_name << ", implementation: " | ||||||
|                 << acquisition_implementation << std::endl; |                 //<< acquisition_implementation << std::endl; | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -278,6 +280,11 @@ GNSSBlockInterface* GNSSBlockFactory::GetBlock( | |||||||
|         block = new GpsL1CaObservables(configuration, role, in_streams, |         block = new GpsL1CaObservables(configuration, role, in_streams, | ||||||
|                 out_streams, queue); |                 out_streams, queue); | ||||||
|     } |     } | ||||||
|  |     else if (implementation.compare("GPS_L1_CA_PVT") == 0) | ||||||
|  |     { | ||||||
|  |         block = new GpsL1CaPvt(configuration, role, in_streams, | ||||||
|  |                 out_streams, queue); | ||||||
|  |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         // Log fatal. This causes execution to stop. |         // Log fatal. This causes execution to stop. | ||||||
|   | |||||||
| @@ -2,6 +2,8 @@ | |||||||
|  * \file gnss_block_factory.h |  * \file gnss_block_factory.h | ||||||
|  * \brief This class implements a factory that returns instances of GNSS blocks. |  * \brief This class implements a factory that returns instances of GNSS blocks. | ||||||
|  * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com |  * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com | ||||||
|  |  *         Luis Esteve, 2011. luis(at)epsilon-formacion.com | ||||||
|  |  *         Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  * |  * | ||||||
|  * This class encapsulates the complexity behind the instantiation |  * This class encapsulates the complexity behind the instantiation | ||||||
|  * of GNSS blocks. |  * of GNSS blocks. | ||||||
|   | |||||||
| @@ -253,11 +253,16 @@ void GNSSFlowgraph::connect() | |||||||
|         DLOG(INFO) << "Channel " << i |         DLOG(INFO) << "Channel " << i | ||||||
|                 << " connected to observables and ready for acquisition"; |                 << " connected to observables and ready for acquisition"; | ||||||
|     } |     } | ||||||
|     // TODO: Enable the observables multichannel output connection to PVT when the PVT implementation is ready |     /*! | ||||||
|  |      * Enabled the observables multichannel output connection to PVT | ||||||
|  |      */ | ||||||
|     try |     try | ||||||
|     { |     { | ||||||
|         top_block_->connect(observables()->get_right_block(), 0, |         for (unsigned int i = 0; i < channels_count_; i++) | ||||||
|                 pvt()->get_left_block(), 0); |         { | ||||||
|  |         	top_block_->connect(observables()->get_right_block(), i, | ||||||
|  |                 pvt()->get_left_block(), i); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     catch (std::exception& e) |     catch (std::exception& e) | ||||||
|     { |     { | ||||||
| @@ -438,14 +443,14 @@ void GNSSFlowgraph::set_satellites_list() | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     std::cout << "Cola de satélites: "; | //    std::cout << "Cola de satélites: "; | ||||||
|     for (std::list<unsigned int>::iterator it = | //    for (std::list<unsigned int>::iterator it = | ||||||
|             available_GPS_satellites_IDs_->begin(); it | //            available_GPS_satellites_IDs_->begin(); it | ||||||
|             != available_GPS_satellites_IDs_->end(); it++) | //            != available_GPS_satellites_IDs_->end(); it++) | ||||||
|     { | //    { | ||||||
|         std::cout << *it << ", "; | //        std::cout << *it << ", "; | ||||||
|     } | //    } | ||||||
|     std::cout << std::endl; | //    std::cout << std::endl; | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -32,17 +32,18 @@ | |||||||
| #ifndef GPS_DEFINES_H | #ifndef GPS_DEFINES_H | ||||||
| #define GPS_DEFINES_H | #define GPS_DEFINES_H | ||||||
|  |  | ||||||
|  | #define NAVIGATION_SOLUTION_RATE_MS 1000 | ||||||
| #define NAVIGATION_OUTPUT_RATE_MS 600 |  | ||||||
|  |  | ||||||
| // GPS CONSTANTS | // GPS CONSTANTS | ||||||
| // JAVI: ADD SYSTEM PREFIX | // JAVI: ADD SYSTEM PREFIX | ||||||
|  |  | ||||||
|  |  | ||||||
| // SEPARATE FILE GPS.H | // SEPARATE FILE GPS.H | ||||||
| const float GPS_C_m_s= 299792458.0;    // The speed of light, [m/ms] | const float GPS_C_m_s= 299792458.0;    // The speed of light, [m/s] | ||||||
|  | const float GPS_C_m_ms= 299792.4580;    // The speed of light, [m/ms] | ||||||
|  |  | ||||||
| const float GPS_STARTOFFSET_ms= 68.802; //[ms] Initial sign. travel time | const float GPS_STARTOFFSET_ms= 68.802; //[ms] Initial sign. travel time | ||||||
| const float GPS_PI = 3.1415926535898; // Pi used in the GPS coordinate system | const double GPS_PI = 3.1415926535898; // Pi used in the GPS coordinate system | ||||||
| // carrier and code frequencies | // carrier and code frequencies | ||||||
| const float GPS_L1_FREQ_HZ	= 1.57542e9; | const float GPS_L1_FREQ_HZ	= 1.57542e9; | ||||||
| const float GPS_L2_FREQ_HZ	= 1.22760e9; | const float GPS_L2_FREQ_HZ	= 1.22760e9; | ||||||
| @@ -59,10 +60,19 @@ const double  F              = -4.442807633e-10; // Constant, [sec/(meter)^(1/2) | |||||||
| // NAVIGATION MESSAGE DEMODULATION AND DECODING | // NAVIGATION MESSAGE DEMODULATION AND DECODING | ||||||
|  |  | ||||||
| #define GPS_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1} | #define GPS_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1} | ||||||
|  | #define GPS_CA_PREAMBLE_LENGTH_BITS 8 | ||||||
|  | #define GPS_CA_TELEMETRY_RATE_BITS_SECOND 50 | ||||||
| #define GPS_WORD_LENGTH 4 // CRC + GPS WORD (-2 -1 0 ... 29) Bits = 4 bytes | #define GPS_WORD_LENGTH 4 // CRC + GPS WORD (-2 -1 0 ... 29) Bits = 4 bytes | ||||||
| #define GPS_SUBFRAME_LENGTH 40 // GPS_WORD_LENGTH x 10 = 40 bytes | #define GPS_SUBFRAME_LENGTH 40 // GPS_WORD_LENGTH x 10 = 40 bytes | ||||||
| #define GPS_SUBFRAME_BITS 300 | #define GPS_SUBFRAME_BITS 300 | ||||||
| #define GPS_WORD_BITS 30 | #define GPS_WORD_BITS 30 | ||||||
|  | /*! | ||||||
|  |  * Maximum Time-Of-Arrival (TOA) difference between satellites for a receiveer operated on Earth surface is 20 ms, according to the GPS orbit model descrived in [1] Pag. 32. | ||||||
|  |  * It should be taken into account to set the buffer size for the PRN start timestamp in the pseudorranges block. | ||||||
|  |  * | ||||||
|  |  * [1] J. Bao-Yen Tsui, Fundamentals of Global Positioning System Receivers. A Software Approach, John Wiley & Sons, Inc., Hoboken, NJ, 2n edition, 2005. | ||||||
|  |  */ | ||||||
|  | #define MAX_TOA_DELAY_MS 20 | ||||||
|  |  | ||||||
| #define num_of_slices(x) sizeof(x)/sizeof(bits_slice) | #define num_of_slices(x) sizeof(x)/sizeof(bits_slice) | ||||||
|  |  | ||||||
| @@ -85,13 +95,26 @@ typedef struct bits_slice{ | |||||||
|  |  | ||||||
| typedef struct gnss_synchro | typedef struct gnss_synchro | ||||||
| { | { | ||||||
|   float preamble_delay_ms; |   double preamble_delay_ms; | ||||||
|   float prn_delay_ms; |   double prn_delay_ms; | ||||||
|  |   double preamble_code_phase_ms; | ||||||
|  |   double preamble_code_phase_correction_ms; | ||||||
|   int satellite_PRN; |   int satellite_PRN; | ||||||
|   int channel_ID; |   int channel_ID; | ||||||
|   bool valid_word; |   bool valid_word; | ||||||
|  |   bool flag_preamble; | ||||||
| } gnss_synchro; | } gnss_synchro; | ||||||
|  |  | ||||||
|  | /*! @ingroup GPS_DEFINES | ||||||
|  |  *  @brief Observables structure, used to feed the PVT block */ | ||||||
|  |  | ||||||
|  | typedef struct gnss_pseudorange | ||||||
|  | { | ||||||
|  |   double pseudorange_m; | ||||||
|  |   double timestamp_ms; | ||||||
|  |   int SV_ID; | ||||||
|  |   bool valid; | ||||||
|  | } gnss_pseudorange; | ||||||
|  |  | ||||||
| /* Constants for scaling the ephemeris found in the data message | /* Constants for scaling the ephemeris found in the data message | ||||||
|         the format is the following: TWO_N5 -> 2^-5, TWO_P4 -> 2^4, PI_TWO_N43 -> Pi*2^-43, etc etc |         the format is the following: TWO_N5 -> 2^-5, TWO_P4 -> 2^4, PI_TWO_N43 -> Pi*2^-43, etc etc | ||||||
|   | |||||||
| @@ -233,27 +233,28 @@ void gps_navigation_message::satpos() | |||||||
|   E   = M; |   E   = M; | ||||||
|  |  | ||||||
|   // --- Iteratively compute eccentric anomaly ---------------------------- |   // --- Iteratively compute eccentric anomaly ---------------------------- | ||||||
|   for (int ii = 1;ii<11;ii++) |   //std::cout<<"d_e_eccentricity="<<d_e_eccentricity<<"\r\n"; | ||||||
|  |   for (int ii = 1;ii<20;ii++) | ||||||
|     { |     { | ||||||
|     E_old   = E; |     E_old   = E; | ||||||
|     E       = M + d_e_eccentricity * sin(E); |     E       = M + d_e_eccentricity * sin(E); | ||||||
|     dE      = fmod(E - E_old,2*GPS_PI); |     dE      = fmod(E - E_old,2*GPS_PI); | ||||||
|     //std::cout<<"dE="<<dE<<std::endl; |     //std::cout<<"dE="<<dE<<std::endl; | ||||||
|     if (abs(dE) < 1E-12) |     if (fabs(dE) < 1e-12) | ||||||
|       { |       { | ||||||
|       //Necessary precision is reached, exit from the loop |       //Necessary precision is reached, exit from the loop | ||||||
|  |       //std::cout<<"Loop break at ii="<<ii<<"\r\n"; | ||||||
|       break; |       break; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   // Reduce eccentric anomaly to between 0 and 360 deg |  | ||||||
|   E   = fmod((E + 2*GPS_PI),(2*GPS_PI)); |  | ||||||
|  |  | ||||||
|   // Compute relativistic correction term |   // Compute relativistic correction term | ||||||
|   d_dtr = F * d_e_eccentricity * d_sqrt_A * sin(E); |   d_dtr = F * d_e_eccentricity * d_sqrt_A * sin(E); | ||||||
|  |  | ||||||
|   // Calculate the true anomaly |   // Calculate the true anomaly | ||||||
|   nu   = atan2(sqrt(1 - d_e_eccentricity*d_e_eccentricity) * sin(E), cos(E)-d_e_eccentricity); |   double tmp_Y=sqrt(1.0 - d_e_eccentricity*d_e_eccentricity) * sin(E); | ||||||
|  |   double tmp_X=cos(E)-d_e_eccentricity; | ||||||
|  |   nu   = atan2(tmp_Y, tmp_X); | ||||||
|  |  | ||||||
|   // Compute angle phi |   // Compute angle phi | ||||||
|   phi = nu + d_OMEGA; |   phi = nu + d_OMEGA; | ||||||
| @@ -266,6 +267,8 @@ void gps_navigation_message::satpos() | |||||||
|  |  | ||||||
|   // Correct radius |   // Correct radius | ||||||
|   r = a * (1 - d_e_eccentricity*cos(E)) +  d_Crc * cos(2*phi) +  d_Crs * sin(2*phi); |   r = a * (1 - d_e_eccentricity*cos(E)) +  d_Crc * cos(2*phi) +  d_Crs * sin(2*phi); | ||||||
|  |  | ||||||
|  |  | ||||||
|   // Correct inclination |   // Correct inclination | ||||||
|   i = d_i_0 + d_IDOT * tk + d_Cic * cos(2*phi) +d_Cis * sin(2*phi); |   i = d_i_0 + d_IDOT * tk + d_Cic * cos(2*phi) +d_Cis * sin(2*phi); | ||||||
|  |  | ||||||
| @@ -275,12 +278,19 @@ void gps_navigation_message::satpos() | |||||||
|   Omega = fmod((Omega + 2*GPS_PI),(2*GPS_PI)); |   Omega = fmod((Omega + 2*GPS_PI),(2*GPS_PI)); | ||||||
|  |  | ||||||
|   // debug |   // debug | ||||||
|   //std::cout<<"tk"<<tk<<std::endl; |   /* | ||||||
|   //std::cout<<"E="<<E<<std::endl; |   if (this->d_channel_ID==0){ | ||||||
|   //std::cout<<"d_dtr="<<d_dtr<<std::endl; | 	  std::cout<<"tk"<<tk<<std::endl; | ||||||
|   //std::cout<<"nu="<<nu<<std::endl; | 	  std::cout<<"E="<<E<<std::endl; | ||||||
|   //std::cout<<"phi="<<phi<<std::endl; | 	  std::cout<<"d_dtr="<<d_dtr<<std::endl; | ||||||
|   //std::cout<<"u="<<u<<" r="<<r<<" Omega="<<Omega<<std::endl; | 	  std::cout<<"nu="<<nu<<std::endl; | ||||||
|  | 	  std::cout<<"phi="<<phi<<std::endl; | ||||||
|  | 	  std::cout<<"u="<<u<<" r="<<r<<" Omega="<<Omega<<std::endl; | ||||||
|  | 	  std::cout<<"i="<<i<<"\r\n"; | ||||||
|  | 	  std::cout<<"tmp_Y="<<tmp_Y<<"\r\n"; | ||||||
|  | 	  std::cout<<"tmp_X="<<tmp_X<<"\r\n"; | ||||||
|  |   } | ||||||
|  |   */ | ||||||
|  |  | ||||||
|   // --- Compute satellite coordinates ------------------------------------ |   // --- Compute satellite coordinates ------------------------------------ | ||||||
|   d_satpos_X = cos(u)*r * cos(Omega) - sin(u)*r * cos(i)*sin(Omega); |   d_satpos_X = cos(u)*r * cos(Omega) - sin(u)*r * cos(i)*sin(Omega); | ||||||
| @@ -304,7 +314,7 @@ int gps_navigation_message::subframe_decoder(char *subframe) | |||||||
|   int subframe_ID=0; |   int subframe_ID=0; | ||||||
|   int SV_data_ID=0; |   int SV_data_ID=0; | ||||||
|   int SV_page=0; |   int SV_page=0; | ||||||
|   double tmp_TOW; |   //double tmp_TOW; | ||||||
|  |  | ||||||
|   unsigned int gps_word; |   unsigned int gps_word; | ||||||
|   // UNPACK BYTES TO BITS AND REMOVE THE CRC REDUNDANCE |   // UNPACK BYTES TO BITS AND REMOVE THE CRC REDUNDANCE | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| project : build-dir ../../build ; | project : build-dir ../../build ; | ||||||
| exe mercurio : main.cc | exe gnss-sdr : main.cc | ||||||
| ../algorithms/acquisition/adapters//gps_l1_ca_gps_sdr_acquisition | ../algorithms/acquisition/adapters//gps_l1_ca_gps_sdr_acquisition | ||||||
| ../algorithms/acquisition/adapters//gps_l1_ca_pcps_acquisition | ../algorithms/acquisition/adapters//gps_l1_ca_pcps_acquisition | ||||||
| ../algorithms/acquisition/adapters//gps_l1_ca_tong_pcps_acquisition | ../algorithms/acquisition/adapters//gps_l1_ca_tong_pcps_acquisition | ||||||
| @@ -20,8 +20,9 @@ exe mercurio : main.cc | |||||||
| ../algorithms/libs//gps_sdr_x86 | ../algorithms/libs//gps_sdr_x86 | ||||||
| ../algorithms/observables/adapters//gps_l1_ca_observables | ../algorithms/observables/adapters//gps_l1_ca_observables | ||||||
| ../algorithms/observables/gnuradio_blocks//gps_l1_ca_observables_cc | ../algorithms/observables/gnuradio_blocks//gps_l1_ca_observables_cc | ||||||
| ../algorithms/observables/libs//rinex_2_1_printer | ../algorithms/PVT/libs//rinex_2_1_printer | ||||||
| ../algorithms/observables/libs//gps_l1_ca_ls_pvt | ../algorithms/PVT/libs//kml_printer | ||||||
|  | ../algorithms/PVT/libs//gps_l1_ca_ls_pvt | ||||||
| ../algorithms/output_filter/adapters//file_output_filter | ../algorithms/output_filter/adapters//file_output_filter | ||||||
| ../algorithms/output_filter/adapters//null_sink_output_filter | ../algorithms/output_filter/adapters//null_sink_output_filter | ||||||
| ../algorithms/signal_source/adapters//file_signal_source | ../algorithms/signal_source/adapters//file_signal_source | ||||||
| @@ -29,6 +30,8 @@ exe mercurio : main.cc | |||||||
| ../algorithms/telemetry_decoder/adapters//gps_l1_ca_telemetry_decoder | ../algorithms/telemetry_decoder/adapters//gps_l1_ca_telemetry_decoder | ||||||
| ../algorithms/telemetry_decoder/gnuradio_blocks//gps_l1_ca_telemetry_decoder_cc | ../algorithms/telemetry_decoder/gnuradio_blocks//gps_l1_ca_telemetry_decoder_cc | ||||||
| ../algorithms/telemetry_decoder/libs//gps_l1_ca_subframe_fsm | ../algorithms/telemetry_decoder/libs//gps_l1_ca_subframe_fsm | ||||||
|  | ../algorithms/PVT/adapters//gps_l1_ca_pvt | ||||||
|  | ../algorithms/PVT/gnuradio_blocks//gps_l1_ca_pvt_cc | ||||||
| ../algorithms/tracking/adapters//gps_l1_ca_dll_pll_tracking | ../algorithms/tracking/adapters//gps_l1_ca_dll_pll_tracking | ||||||
| ../algorithms/tracking/adapters//gps_l1_ca_dll_fll_pll_tracking | ../algorithms/tracking/adapters//gps_l1_ca_dll_fll_pll_tracking | ||||||
| ../algorithms/tracking/gnuradio_blocks//gps_l1_ca_dll_pll_tracking_cc | ../algorithms/tracking/gnuradio_blocks//gps_l1_ca_dll_pll_tracking_cc | ||||||
| @@ -36,8 +39,8 @@ exe mercurio : main.cc | |||||||
| ../algorithms/tracking/libs//tracking_discriminators | ../algorithms/tracking/libs//tracking_discriminators | ||||||
| ../algorithms/tracking/libs//CN_estimators | ../algorithms/tracking/libs//CN_estimators | ||||||
| ../algorithms/tracking/libs//tracking_FLL_PLL_filter | ../algorithms/tracking/libs//tracking_FLL_PLL_filter | ||||||
| ../algorithms/tracking/libs//tracking_2rd_PLL_filter | ../algorithms/tracking/libs//tracking_2nd_PLL_filter | ||||||
| ../algorithms/tracking/libs//tracking_2rd_DLL_filter | ../algorithms/tracking/libs//tracking_2nd_DLL_filter | ||||||
| ../core/libs//INIReader | ../core/libs//INIReader | ||||||
| ../core/libs//ini | ../core/libs//ini | ||||||
| ../core/libs//string_converter | ../core/libs//string_converter | ||||||
| @@ -54,4 +57,4 @@ exe mercurio : main.cc | |||||||
| ../..//gnuradio-core | ../..//gnuradio-core | ||||||
| ../..//gnuradio-usrp ; | ../..//gnuradio-usrp ; | ||||||
|  |  | ||||||
| install ../../install : mercurio ; | install ../../install : gnss-sdr ; | ||||||
|   | |||||||
| @@ -64,6 +64,7 @@ int main(int argc, char** argv) | |||||||
|             + |             + | ||||||
|             "See COPYING file to see a copy of the General Public License\n \n"); |             "See COPYING file to see a copy of the General Public License\n \n"); | ||||||
|  |  | ||||||
|  |     std::cout<<"Initializing GNSS-SDR... Please wait"<<"\r\n"; | ||||||
|     google::SetUsageMessage(intro_help); |     google::SetUsageMessage(intro_help); | ||||||
|     google::InitGoogleLogging(argv[0]); |     google::InitGoogleLogging(argv[0]); | ||||||
|     google::ParseCommandLineFlags(&argc, &argv, true); |     google::ParseCommandLineFlags(&argc, &argv, true); | ||||||
| @@ -74,5 +75,6 @@ int main(int argc, char** argv) | |||||||
|     control_thread->run(); |     control_thread->run(); | ||||||
|  |  | ||||||
|     delete control_thread; |     delete control_thread; | ||||||
|  |     std::cout<<"GNSS-SDR program ended"<<"\r\n"; | ||||||
|     //google::ShutDownCommandLineFlags(); |     //google::ShutDownCommandLineFlags(); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										83
									
								
								src/utils/matlab/gps_l1_ca_dll_fll_pll_plot_sample.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/utils/matlab/gps_l1_ca_dll_fll_pll_plot_sample.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | |||||||
|  | % /*! | ||||||
|  | %  * \file gps_l1_ca_dll_fll_pll_plot_sample.m | ||||||
|  | %  * \brief Read GNSS-SDR Tracking dump binary file using the provided | ||||||
|  | %  function and plot some internal variables | ||||||
|  | %  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  * | ||||||
|  | %  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is a software defined Global Navigation | ||||||
|  | %  *          Satellite Systems receiver | ||||||
|  | %  * | ||||||
|  | %  * This file is part of GNSS-SDR. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  | %  * it under the terms of the GNU General Public License as published by | ||||||
|  | %  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  | %  * at your option) any later version. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  | %  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | %  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | %  * GNU General Public License for more details. | ||||||
|  | %  * | ||||||
|  | %  * You should have received a copy of the GNU General Public License | ||||||
|  | %  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | %  * | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  */  | ||||||
|  | close all; | ||||||
|  | clear all; | ||||||
|  | samplingFreq       = 64e6/16;     %[Hz] | ||||||
|  | channels=6; | ||||||
|  | path='/home/javier/workspace/gnss-sdr/trunk/install/'; | ||||||
|  | clear PRN_absolute_sample_start; | ||||||
|  | for N=1:1:channels | ||||||
|  |     tracking_log_path=[path 'tracking_ch_' num2str(N-1) '.dat']; | ||||||
|  |     GNSS_tracking(N)= gps_l1_ca_dll_fll_pll_read_tracking_dump(tracking_log_path);    | ||||||
|  | end | ||||||
|  |  | ||||||
|  | % GNSS-SDR format conversion to MATLAB GPS receiver | ||||||
|  |  | ||||||
|  | for N=1:1:channels | ||||||
|  |         trackResults(N).status='T'; %fake track | ||||||
|  |         trackResults(N).codeFreq=GNSS_tracking(N).code_freq_hz.'; | ||||||
|  |         trackResults(N).carrFreq=GNSS_tracking(N).carrier_doppler_hz.'; | ||||||
|  |         trackResults(N).dllDiscr       = GNSS_tracking(N).code_error_chips.'; | ||||||
|  |         trackResults(N).dllDiscrFilt   = GNSS_tracking(N).code_phase_samples.'; | ||||||
|  |         trackResults(N).pllDiscr       = GNSS_tracking(N).PLL_discriminator_hz.'; | ||||||
|  |         trackResults(N).pllDiscrFilt   = GNSS_tracking(N).carr_nco.'; | ||||||
|  |  | ||||||
|  |         trackResults(N).I_P=GNSS_tracking(N).prompt_I.'; | ||||||
|  |         trackResults(N).Q_P=GNSS_tracking(N).prompt_Q.'; | ||||||
|  |  | ||||||
|  |         trackResults(N).I_E= GNSS_tracking(N).E.'; | ||||||
|  |         trackResults(N).I_L = GNSS_tracking(N).L.'; | ||||||
|  |         trackResults(N).Q_E = zeros(1,length(GNSS_tracking(N).E)); | ||||||
|  |         trackResults(N).Q_L =zeros(1,length(GNSS_tracking(N).E)); | ||||||
|  |         trackResults(N).PRN=N; %fake PRN | ||||||
|  |          | ||||||
|  |         % Use original MATLAB tracking plot function | ||||||
|  |         settings.numberOfChannels=channels; | ||||||
|  |         settings.msToProcess=length(GNSS_tracking(N).E); | ||||||
|  |         plotTracking(N,trackResults,settings) | ||||||
|  | end | ||||||
|  |  | ||||||
|  |  | ||||||
|  | % for N=1:1:channels | ||||||
|  | %  figure; | ||||||
|  | %  plot([GNSS_tracking(N).E,GNSS_tracking(N).P,GNSS_tracking(N).L],'-*'); | ||||||
|  | %  title(['Early, Prompt, and Late correlator absolute value output for channel ' num2str(N)']); | ||||||
|  | %  figure; | ||||||
|  | %  plot(GNSS_tracking(N).prompt_I,GNSS_tracking(N).prompt_Q,'+'); | ||||||
|  | %  title(['Navigation constellation plot for channel ' num2str(N)]); | ||||||
|  | %  figure; | ||||||
|  | %   | ||||||
|  | %  plot(GNSS_tracking(N).prompt_Q,'r'); | ||||||
|  | %  hold on; | ||||||
|  | %  plot(GNSS_tracking(N).prompt_I); | ||||||
|  | %  title(['Navigation symbols I(red) Q(blue) for channel ' num2str(N)]); | ||||||
|  | % end | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										82
									
								
								src/utils/matlab/gps_l1_ca_dll_pll_plot_sample.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/utils/matlab/gps_l1_ca_dll_pll_plot_sample.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | |||||||
|  | % /*! | ||||||
|  | %  * \file gps_l1_ca_dll_pll_plot_sample.m | ||||||
|  | %  * \brief Read GNSS-SDR Tracking dump binary file using the provided | ||||||
|  | %  function and plot some internal variables | ||||||
|  | %  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  * | ||||||
|  | %  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is a software defined Global Navigation | ||||||
|  | %  *          Satellite Systems receiver | ||||||
|  | %  * | ||||||
|  | %  * This file is part of GNSS-SDR. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  | %  * it under the terms of the GNU General Public License as published by | ||||||
|  | %  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  | %  * at your option) any later version. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  | %  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | %  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | %  * GNU General Public License for more details. | ||||||
|  | %  * | ||||||
|  | %  * You should have received a copy of the GNU General Public License | ||||||
|  | %  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | %  * | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  */  | ||||||
|  | close all; | ||||||
|  | clear all; | ||||||
|  | samplingFreq       = 64e6/16;     %[Hz] | ||||||
|  | channels=6; | ||||||
|  | path='/home/javier/workspace/gnss-sdr/trunk/install/'; | ||||||
|  | clear PRN_absolute_sample_start; | ||||||
|  | for N=1:1:channels | ||||||
|  |     tracking_log_path=[path 'tracking_ch_' num2str(N-1) '.dat']; | ||||||
|  |     GNSS_tracking(N)= gps_l1_ca_dll_pll_read_tracking_dump(tracking_log_path);    | ||||||
|  | end | ||||||
|  |  | ||||||
|  | % GNSS-SDR format conversion to MATLAB GPS receiver | ||||||
|  |  | ||||||
|  | for N=1:1:channels | ||||||
|  |         trackResults(N).status='T'; %fake track | ||||||
|  |         trackResults(N).codeFreq=GNSS_tracking(N).code_freq_hz.'; | ||||||
|  |         trackResults(N).carrFreq=GNSS_tracking(N).carrier_doppler_hz.'; | ||||||
|  |         trackResults(N).dllDiscr       = GNSS_tracking(N).code_error.'; | ||||||
|  |         trackResults(N).dllDiscrFilt   = GNSS_tracking(N).code_nco.'; | ||||||
|  |         trackResults(N).pllDiscr       = GNSS_tracking(N).carr_error.'; | ||||||
|  |         trackResults(N).pllDiscrFilt   = GNSS_tracking(N).carr_nco.'; | ||||||
|  |  | ||||||
|  |         trackResults(N).I_P=GNSS_tracking(N).prompt_I.'; | ||||||
|  |         trackResults(N).Q_P=GNSS_tracking(N).prompt_Q.'; | ||||||
|  |  | ||||||
|  |         trackResults(N).I_E= GNSS_tracking(N).E.'; | ||||||
|  |         trackResults(N).I_L = GNSS_tracking(N).L.'; | ||||||
|  |         trackResults(N).Q_E = zeros(1,length(GNSS_tracking(N).E)); | ||||||
|  |         trackResults(N).Q_L =zeros(1,length(GNSS_tracking(N).E)); | ||||||
|  |         trackResults(N).PRN=N; %fake PRN | ||||||
|  |          | ||||||
|  |         % Use original MATLAB tracking plot function | ||||||
|  |         settings.numberOfChannels=channels; | ||||||
|  |         settings.msToProcess=length(GNSS_tracking(N).E); | ||||||
|  |         plotTracking(N,trackResults,settings) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | % for N=1:1:channels | ||||||
|  | %  figure; | ||||||
|  | %  plot([GNSS_tracking(N).E,GNSS_tracking(N).P,GNSS_tracking(N).L],'-*'); | ||||||
|  | %  title(['Early, Prompt, and Late correlator absolute value output for channel ' num2str(N)']); | ||||||
|  | %  figure; | ||||||
|  | %  plot(GNSS_tracking(N).prompt_I,GNSS_tracking(N).prompt_Q,'+'); | ||||||
|  | %  title(['Navigation constellation plot for channel ' num2str(N)]); | ||||||
|  | %  figure; | ||||||
|  | %   | ||||||
|  | %  plot(GNSS_tracking(N).prompt_Q,'r'); | ||||||
|  | %  hold on; | ||||||
|  | %  plot(GNSS_tracking(N).prompt_I); | ||||||
|  | %  title(['Navigation symbols I(red) Q(blue) for channel ' num2str(N)]); | ||||||
|  | % end | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										81
									
								
								src/utils/matlab/gps_l1_ca_pvt_plot_sample_agilent_cap2.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/utils/matlab/gps_l1_ca_pvt_plot_sample_agilent_cap2.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | |||||||
|  | % /*! | ||||||
|  | %  * \file gps_l1_ca_pvt_plot_sample.m | ||||||
|  | %  * \brief Read GNSS-SDR PVT dump binary file using the provided | ||||||
|  | %  function and plot some internal variables | ||||||
|  | %  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  * | ||||||
|  | %  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is a software defined Global Navigation | ||||||
|  | %  *          Satellite Systems receiver | ||||||
|  | %  * | ||||||
|  | %  * This file is part of GNSS-SDR. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  | %  * it under the terms of the GNU General Public License as published by | ||||||
|  | %  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  | %  * at your option) any later version. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  | %  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | %  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | %  * GNU General Public License for more details. | ||||||
|  | %  * | ||||||
|  | %  * You should have received a copy of the GNU General Public License | ||||||
|  | %  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | %  * | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  */  | ||||||
|  |  | ||||||
|  | close all; | ||||||
|  | clear all; | ||||||
|  |  | ||||||
|  | % True position of the antenna in UTM system (if known). Otherwise enter | ||||||
|  | % all NaN's and mean position will be used as a reference . | ||||||
|  | settings.truePosition.E     = nan; | ||||||
|  | settings.truePosition.N     = nan; | ||||||
|  | settings.truePosition.U     = nan; | ||||||
|  |  | ||||||
|  | settings.navSolPeriod=100; %[ms] | ||||||
|  |  | ||||||
|  | filename='/home/javier/workspace/gnss-sdr/trunk/install/PVT.dat'; | ||||||
|  |  | ||||||
|  | navSolutions = gps_l1_ca_pvt_read_pvt_dump (filename); | ||||||
|  |  | ||||||
|  | % Reference position for Agilent cap2.dat (San Francisco static scenario) | ||||||
|  | % Scenario latitude  is 37.8194388888889  N37 49 9.98 | ||||||
|  | % Scenario longitude is -122.4784944  W122 28 42.58 | ||||||
|  | % Scenario elevation is 35 meters. | ||||||
|  | lat=[37 49 9.98]; | ||||||
|  | long=[-122 -28 -42.58]; | ||||||
|  |  | ||||||
|  | lat_deg=dms2deg(lat); | ||||||
|  | long_deg=dms2deg(long); | ||||||
|  |  | ||||||
|  | h=35; | ||||||
|  | %Choices i of Reference Ellipsoid | ||||||
|  | %   1. International Ellipsoid 1924 | ||||||
|  | %   2. International Ellipsoid 1967 | ||||||
|  | %   3. World Geodetic System 1972 | ||||||
|  | %   4. Geodetic Reference System 1980 | ||||||
|  | %   5. World Geodetic System 1984 | ||||||
|  | [X, Y, Z]=geo2cart(lat, long, h, 5); % geographical to cartesian conversion | ||||||
|  |  | ||||||
|  | %=== Convert to UTM coordinate system ============================= | ||||||
|  | utmZone = findUtmZone(lat_deg, long_deg);  | ||||||
|  |  | ||||||
|  |  [settings.truePosition.E, ... | ||||||
|  |   settings.truePosition.N, ... | ||||||
|  |   settings.truePosition.U] = cart2utm(X, Y, Z, utmZone); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | for k=1:1:length(navSolutions.X) | ||||||
|  |     [navSolutions.E(k), ... | ||||||
|  |      navSolutions.N(k), ... | ||||||
|  |      navSolutions.U(k)]=cart2utm(navSolutions.X(k), navSolutions.Y(k), navSolutions.Z(k), utmZone); | ||||||
|  | end | ||||||
|  |  | ||||||
|  | plot_skyplot=0; | ||||||
|  | plotNavigation(navSolutions,settings,plot_skyplot); | ||||||
|  |  | ||||||
							
								
								
									
										60
									
								
								src/utils/matlab/libs/geoFunctions/cart2geo.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/utils/matlab/libs/geoFunctions/cart2geo.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | function [phi, lambda, h] = cart2geo(X, Y, Z, i) | ||||||
|  | %CART2GEO Conversion of Cartesian coordinates (X,Y,Z) to geographical | ||||||
|  | %coordinates (phi, lambda, h) on a selected reference ellipsoid. | ||||||
|  | % | ||||||
|  | %[phi, lambda, h] = cart2geo(X, Y, Z, i); | ||||||
|  | % | ||||||
|  | %   Choices i of Reference Ellipsoid for Geographical Coordinates | ||||||
|  | %          	  1. International Ellipsoid 1924 | ||||||
|  | %	          2. International Ellipsoid 1967 | ||||||
|  | %	          3. World Geodetic System 1972 | ||||||
|  | %	          4. Geodetic Reference System 1980 | ||||||
|  | %	          5. World Geodetic System 1984 | ||||||
|  |  | ||||||
|  | %Kai Borre 10-13-98 | ||||||
|  | %Copyright (c) by Kai Borre | ||||||
|  | %Revision: 1.0   Date: 1998/10/23   | ||||||
|  | % | ||||||
|  | % CVS record: | ||||||
|  | % $Id: cart2geo.m,v 1.1.2.3 2007/01/29 15:22:49 dpl Exp $ | ||||||
|  | %========================================================================== | ||||||
|  |  | ||||||
|  | a = [6378388 6378160 6378135 6378137 6378137]; | ||||||
|  | f = [1/297 1/298.247 1/298.26 1/298.257222101 1/298.257223563]; | ||||||
|  |  | ||||||
|  | lambda = atan2(Y,X); | ||||||
|  | ex2 = (2-f(i))*f(i)/((1-f(i))^2); | ||||||
|  | c = a(i)*sqrt(1+ex2); | ||||||
|  | phi = atan(Z/((sqrt(X^2+Y^2)*(1-(2-f(i)))*f(i)))); | ||||||
|  |  | ||||||
|  | h = 0.1; oldh = 0; | ||||||
|  | iterations = 0; | ||||||
|  | while abs(h-oldh) > 1.e-12 | ||||||
|  |    oldh = h; | ||||||
|  |    N = c/sqrt(1+ex2*cos(phi)^2); | ||||||
|  |    phi = atan(Z/((sqrt(X^2+Y^2)*(1-(2-f(i))*f(i)*N/(N+h))))); | ||||||
|  |    h = sqrt(X^2+Y^2)/cos(phi)-N; | ||||||
|  |     | ||||||
|  |    iterations = iterations + 1; | ||||||
|  |    if iterations > 100 | ||||||
|  |        fprintf('Failed to approximate h with desired precision. h-oldh: %e.\n', h-oldh); | ||||||
|  |        break; | ||||||
|  |    end    | ||||||
|  | end | ||||||
|  |  | ||||||
|  | phi = phi*180/pi; | ||||||
|  | % b = zeros(1,3); | ||||||
|  | % b(1,1) = fix(phi); | ||||||
|  | % b(2,1) = fix(rem(phi,b(1,1))*60); | ||||||
|  | % b(3,1) = (phi-b(1,1)-b(1,2)/60)*3600; | ||||||
|  |  | ||||||
|  | lambda = lambda*180/pi; | ||||||
|  | % l = zeros(1,3); | ||||||
|  | % l(1,1) = fix(lambda); | ||||||
|  | % l(2,1) = fix(rem(lambda,l(1,1))*60); | ||||||
|  | % l(3,1) = (lambda-l(1,1)-l(1,2)/60)*3600; | ||||||
|  |  | ||||||
|  | %fprintf('\n     phi =%3.0f %3.0f %8.5f',b(1),b(2),b(3)) | ||||||
|  | %fprintf('\n  lambda =%3.0f %3.0f %8.5f',l(1),l(2),l(3)) | ||||||
|  | %fprintf('\n       h =%14.3f\n',h) | ||||||
|  | %%%%%%%%%%%%%% end cart2geo.m %%%%%%%%%%%%%%%%%%% | ||||||
							
								
								
									
										176
									
								
								src/utils/matlab/libs/geoFunctions/cart2utm.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								src/utils/matlab/libs/geoFunctions/cart2utm.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,176 @@ | |||||||
|  | function [E, N, U] = cart2utm(X, Y, Z, zone) | ||||||
|  | %CART2UTM  Transformation of (X,Y,Z) to (N,E,U) in UTM, zone 'zone'. | ||||||
|  | % | ||||||
|  | %[E, N, U] = cart2utm(X, Y, Z, zone); | ||||||
|  | % | ||||||
|  | %   Inputs: | ||||||
|  | %       X,Y,Z       - Cartesian coordinates. Coordinates are referenced | ||||||
|  | %                   with respect to the International Terrestrial Reference | ||||||
|  | %                   Frame 1996 (ITRF96) | ||||||
|  | %       zone        - UTM zone of the given position | ||||||
|  | % | ||||||
|  | %   Outputs: | ||||||
|  | %      E, N, U      - UTM coordinates (Easting, Northing, Uping) | ||||||
|  |  | ||||||
|  | %Kai Borre -11-1994 | ||||||
|  | %Copyright (c) by Kai Borre | ||||||
|  | % | ||||||
|  | % CVS record: | ||||||
|  | % $Id: cart2utm.m,v 1.1.1.1.2.6 2007/01/30 09:45:12 dpl Exp $ | ||||||
|  |  | ||||||
|  | %This implementation is based upon | ||||||
|  | %O. Andersson & K. Poder (1981) Koordinattransformationer | ||||||
|  | %  ved Geod\ae{}tisk Institut. Landinspekt\oe{}ren | ||||||
|  | %  Vol. 30: 552--571 and Vol. 31: 76 | ||||||
|  | % | ||||||
|  | %An excellent, general reference (KW) is | ||||||
|  | %R. Koenig & K.H. Weise (1951) Mathematische Grundlagen der | ||||||
|  | %  h\"oheren Geod\"asie und Kartographie. | ||||||
|  | %  Erster Band, Springer Verlag | ||||||
|  |  | ||||||
|  | % Explanation of variables used: | ||||||
|  | % f	   flattening of ellipsoid | ||||||
|  | % a	   semi major axis in m | ||||||
|  | % m0	   1 - scale at central meridian; for UTM 0.0004 | ||||||
|  | % Q_n	   normalized meridian quadrant | ||||||
|  | % E0	   Easting of central meridian | ||||||
|  | % L0	   Longitude of central meridian | ||||||
|  | % bg	   constants for ellipsoidal geogr. to spherical geogr. | ||||||
|  | % gb	   constants for spherical geogr. to ellipsoidal geogr. | ||||||
|  | % gtu	   constants for ellipsoidal N, E to spherical N, E | ||||||
|  | % utg	   constants for spherical N, E to ellipoidal N, E | ||||||
|  | % tolutm	tolerance for utm, 1.2E-10*meridian quadrant | ||||||
|  | % tolgeo	tolerance for geographical, 0.00040 second of arc | ||||||
|  |  | ||||||
|  | % B, L refer to latitude and longitude. Southern latitude is negative | ||||||
|  | % International ellipsoid of 1924, valid for ED50 | ||||||
|  |  | ||||||
|  | a     = 6378388; | ||||||
|  | f     = 1/297; | ||||||
|  | ex2   = (2-f)*f / ((1-f)^2); | ||||||
|  | c     = a * sqrt(1+ex2); | ||||||
|  | vec   = [X; Y; Z-4.5]; | ||||||
|  | alpha = .756e-6; | ||||||
|  | R     = [ 1       -alpha  0; | ||||||
|  |             alpha	1       0; | ||||||
|  |             0       0       1]; | ||||||
|  | trans = [89.5; 93.8; 127.6]; | ||||||
|  | scale = 0.9999988; | ||||||
|  | v     = scale*R*vec + trans;	  % coordinate vector in ED50 | ||||||
|  | L     = atan2(v(2), v(1)); | ||||||
|  | N1    = 6395000;		          % preliminary value | ||||||
|  | B     = atan2(v(3)/((1-f)^2*N1), norm(v(1:2))/N1); % preliminary value | ||||||
|  | U     = 0.1;  oldU = 0; | ||||||
|  |  | ||||||
|  | iterations = 0; | ||||||
|  | while abs(U-oldU) > 1.e-4 | ||||||
|  |     oldU = U; | ||||||
|  |     N1   = c/sqrt(1+ex2*(cos(B))^2); | ||||||
|  |     B    = atan2(v(3)/((1-f)^2*N1+U), norm(v(1:2))/(N1+U) ); | ||||||
|  |     U    = norm(v(1:2))/cos(B)-N1; | ||||||
|  | 	 | ||||||
|  |    iterations = iterations + 1; | ||||||
|  |    if iterations > 100 | ||||||
|  |        fprintf('Failed to approximate U with desired precision. U-oldU: %e.\n', U-oldU); | ||||||
|  |        break; | ||||||
|  |    end	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %Normalized meridian quadrant, KW p. 50 (96), p. 19 (38b), p. 5 (21) | ||||||
|  | m0  = 0.0004; | ||||||
|  | n   = f / (2-f); | ||||||
|  | m   = n^2 * (1/4 + n*n/64); | ||||||
|  | w   = (a*(-n-m0+m*(1-m0))) / (1+n); | ||||||
|  | Q_n = a + w; | ||||||
|  |  | ||||||
|  | %Easting and longitude of central meridian | ||||||
|  | E0      = 500000; | ||||||
|  | L0      = (zone-30)*6 - 3; | ||||||
|  |  | ||||||
|  | %Check tolerance for reverse transformation | ||||||
|  | tolutm  = pi/2 * 1.2e-10 * Q_n; | ||||||
|  | tolgeo  = 0.000040; | ||||||
|  |  | ||||||
|  | %Coefficients of trigonometric series | ||||||
|  |  | ||||||
|  | %ellipsoidal to spherical geographical, KW p. 186--187, (51)-(52) | ||||||
|  | % bg[1] = n*(-2 + n*(2/3    + n*(4/3	  + n*(-82/45)))); | ||||||
|  | % bg[2] = n^2*(5/3    + n*(-16/15 + n*(-13/9))); | ||||||
|  | % bg[3] = n^3*(-26/15 + n*34/21); | ||||||
|  | % bg[4] = n^4*1237/630; | ||||||
|  |  | ||||||
|  | %spherical to ellipsoidal geographical, KW p. 190--191, (61)-(62) | ||||||
|  | % gb[1] = n*(2	      + n*(-2/3    + n*(-2	 + n*116/45))); | ||||||
|  | % gb[2] = n^2*(7/3    + n*(-8/5 + n*(-227/45))); | ||||||
|  | % gb[3] = n^3*(56/15 + n*(-136/35)); | ||||||
|  | % gb[4] = n^4*4279/630; | ||||||
|  |  | ||||||
|  | %spherical to ellipsoidal N, E, KW p. 196, (69) | ||||||
|  | % gtu[1] = n*(1/2	  + n*(-2/3    + n*(5/16     + n*41/180))); | ||||||
|  | % gtu[2] = n^2*(13/48	  + n*(-3/5 + n*557/1440)); | ||||||
|  | % gtu[3] = n^3*(61/240	 + n*(-103/140)); | ||||||
|  | % gtu[4] = n^4*49561/161280; | ||||||
|  |  | ||||||
|  | %ellipsoidal to spherical N, E, KW p. 194, (65) | ||||||
|  | % utg[1] = n*(-1/2	   + n*(2/3    + n*(-37/96	+ n*1/360))); | ||||||
|  | % utg[2] = n^2*(-1/48	  + n*(-1/15 + n*437/1440)); | ||||||
|  | % utg[3] = n^3*(-17/480 + n*37/840); | ||||||
|  | % utg[4] = n^4*(-4397/161280); | ||||||
|  |  | ||||||
|  | %With f = 1/297 we get | ||||||
|  |  | ||||||
|  | bg = [-3.37077907e-3; | ||||||
|  |        4.73444769e-6; | ||||||
|  |       -8.29914570e-9; | ||||||
|  |        1.58785330e-11]; | ||||||
|  |  | ||||||
|  | gb = [ 3.37077588e-3; | ||||||
|  |        6.62769080e-6; | ||||||
|  |        1.78718601e-8; | ||||||
|  |        5.49266312e-11]; | ||||||
|  |  | ||||||
|  | gtu = [ 8.41275991e-4; | ||||||
|  |         7.67306686e-7; | ||||||
|  |         1.21291230e-9; | ||||||
|  |         2.48508228e-12]; | ||||||
|  |  | ||||||
|  | utg = [-8.41276339e-4; | ||||||
|  |        -5.95619298e-8; | ||||||
|  |        -1.69485209e-10; | ||||||
|  |        -2.20473896e-13]; | ||||||
|  |  | ||||||
|  | %Ellipsoidal latitude, longitude to spherical latitude, longitude | ||||||
|  | neg_geo = 'FALSE'; | ||||||
|  |  | ||||||
|  | if B < 0 | ||||||
|  |     neg_geo = 'TRUE '; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | Bg_r    = abs(B); | ||||||
|  | [res_clensin] = clsin(bg, 4, 2*Bg_r); | ||||||
|  | Bg_r    = Bg_r + res_clensin; | ||||||
|  | L0      = L0*pi / 180; | ||||||
|  | Lg_r    = L - L0; | ||||||
|  |  | ||||||
|  | %Spherical latitude, longitude to complementary spherical latitude | ||||||
|  | %  i.e. spherical N, E | ||||||
|  | cos_BN  = cos(Bg_r); | ||||||
|  | Np      = atan2(sin(Bg_r), cos(Lg_r)*cos_BN); | ||||||
|  | Ep      = atanh(sin(Lg_r) * cos_BN); | ||||||
|  |  | ||||||
|  | %Spherical normalized N, E to ellipsoidal N, E | ||||||
|  | Np      = 2 * Np; | ||||||
|  | Ep      = 2 * Ep; | ||||||
|  | [dN, dE] = clksin(gtu, 4, Np, Ep); | ||||||
|  | Np      = Np/2; | ||||||
|  | Ep      = Ep/2; | ||||||
|  | Np      = Np + dN; | ||||||
|  | Ep      = Ep + dE; | ||||||
|  | N       = Q_n * Np; | ||||||
|  | E       = Q_n*Ep + E0; | ||||||
|  |  | ||||||
|  | if neg_geo == 'TRUE ' | ||||||
|  |     N = -N + 20000000; | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%% end cart2utm.m %%%%%%%%%%%%%%%%%%%% | ||||||
							
								
								
									
										28
									
								
								src/utils/matlab/libs/geoFunctions/check_t.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/utils/matlab/libs/geoFunctions/check_t.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | function corrTime = check_t(time) | ||||||
|  | %CHECK_T accounting for beginning or end of week crossover. | ||||||
|  | % | ||||||
|  | %corrTime = check_t(time); | ||||||
|  | % | ||||||
|  | %   Inputs: | ||||||
|  | %       time        - time in seconds | ||||||
|  | % | ||||||
|  | %   Outputs: | ||||||
|  | %       corrTime    - corrected time (seconds) | ||||||
|  |  | ||||||
|  | %Kai Borre 04-01-96 | ||||||
|  | %Copyright (c) by Kai Borre | ||||||
|  | % | ||||||
|  | % CVS record: | ||||||
|  | % $Id: check_t.m,v 1.1.1.1.2.4 2006/08/22 13:45:59 dpl Exp $ | ||||||
|  | %========================================================================== | ||||||
|  |  | ||||||
|  | half_week = 302400;     % seconds | ||||||
|  |  | ||||||
|  | corrTime = time; | ||||||
|  |  | ||||||
|  | if time > half_week | ||||||
|  |     corrTime = time - 2*half_week; | ||||||
|  | elseif time < -half_week | ||||||
|  |     corrTime = time + 2*half_week; | ||||||
|  | end | ||||||
|  | %%%%%%% end check_t.m  %%%%%%%%%%%%%%%%% | ||||||
							
								
								
									
										38
									
								
								src/utils/matlab/libs/geoFunctions/clksin.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/utils/matlab/libs/geoFunctions/clksin.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | function [re, im] = clksin(ar, degree, arg_real, arg_imag) | ||||||
|  | %Clenshaw summation of sinus with complex argument | ||||||
|  | %[re, im] = clksin(ar, degree, arg_real, arg_imag); | ||||||
|  |  | ||||||
|  | % Written by Kai Borre | ||||||
|  | % December 20, 1995 | ||||||
|  | % | ||||||
|  | % See also WGS2UTM or CART2UTM | ||||||
|  | % | ||||||
|  | % CVS record: | ||||||
|  | % $Id: clksin.m,v 1.1.1.1.2.4 2006/08/22 13:45:59 dpl Exp $ | ||||||
|  | %========================================================================== | ||||||
|  |  | ||||||
|  | sin_arg_r   = sin(arg_real); | ||||||
|  | cos_arg_r   = cos(arg_real); | ||||||
|  | sinh_arg_i  = sinh(arg_imag); | ||||||
|  | cosh_arg_i  = cosh(arg_imag); | ||||||
|  |  | ||||||
|  | r           = 2 * cos_arg_r * cosh_arg_i; | ||||||
|  | i           =-2 * sin_arg_r * sinh_arg_i; | ||||||
|  |  | ||||||
|  | hr1 = 0; hr = 0; hi1 = 0; hi = 0; | ||||||
|  |  | ||||||
|  | for t = degree : -1 : 1 | ||||||
|  |     hr2 = hr1; | ||||||
|  |     hr1 = hr; | ||||||
|  |     hi2 = hi1; | ||||||
|  |     hi1 = hi; | ||||||
|  |     z   = ar(t) + r*hr1 - i*hi - hr2; | ||||||
|  |     hi  =         i*hr1 + r*hi1 - hi2; | ||||||
|  |     hr  = z; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | r   = sin_arg_r * cosh_arg_i; | ||||||
|  | i   = cos_arg_r * sinh_arg_i; | ||||||
|  |  | ||||||
|  | re  = r*hr - i*hi; | ||||||
|  | im  = r*hi + i*hr; | ||||||
							
								
								
									
										26
									
								
								src/utils/matlab/libs/geoFunctions/clsin.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/utils/matlab/libs/geoFunctions/clsin.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | function  result = clsin(ar, degree, argument) | ||||||
|  | %Clenshaw summation of sinus of argument. | ||||||
|  | % | ||||||
|  | %result = clsin(ar, degree, argument); | ||||||
|  |  | ||||||
|  | % Written by Kai Borre | ||||||
|  | % December 20, 1995 | ||||||
|  | % | ||||||
|  | % See also WGS2UTM or CART2UTM | ||||||
|  | % | ||||||
|  | % CVS record: | ||||||
|  | % $Id: clsin.m,v 1.1.1.1.2.4 2006/08/22 13:45:59 dpl Exp $ | ||||||
|  | %========================================================================== | ||||||
|  |  | ||||||
|  | cos_arg = 2 * cos(argument); | ||||||
|  | hr1     = 0; | ||||||
|  | hr      = 0; | ||||||
|  |  | ||||||
|  | for t = degree : -1 : 1 | ||||||
|  |    hr2 = hr1; | ||||||
|  |    hr1 = hr; | ||||||
|  |    hr  = ar(t) + cos_arg*hr1 - hr2; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | result = hr * sin(argument); | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%% end clsin.m  %%%%%%%%%%%%%%%%%%%%% | ||||||
							
								
								
									
										43
									
								
								src/utils/matlab/libs/geoFunctions/deg2dms.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/utils/matlab/libs/geoFunctions/deg2dms.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | function dmsOutput = deg2dms(deg) | ||||||
|  | %DEG2DMS  Conversion of degrees to degrees, minutes, and seconds. | ||||||
|  | %The output format (dms format) is: (degrees*100 + minutes + seconds/100) | ||||||
|  |  | ||||||
|  | % Written by Kai Borre | ||||||
|  | % February 7, 2001 | ||||||
|  | % Updated by Darius Plausinaitis | ||||||
|  |  | ||||||
|  | %%% Save the sign for later processing | ||||||
|  | neg_arg = false; | ||||||
|  | if deg < 0 | ||||||
|  |     % Only positive numbers should be used while spliting into deg/min/sec | ||||||
|  |     deg     = -deg; | ||||||
|  |     neg_arg = true;     | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %%% Split degrees minutes and seconds | ||||||
|  | int_deg   = floor(deg); | ||||||
|  | decimal   = deg - int_deg; | ||||||
|  | min_part  = decimal*60; | ||||||
|  | min       = floor(min_part); | ||||||
|  | sec_part  = min_part - floor(min_part); | ||||||
|  | sec       = sec_part*60; | ||||||
|  |  | ||||||
|  | %%% Check for overflow | ||||||
|  | if sec == 60 | ||||||
|  |     min     = min + 1; | ||||||
|  |     sec     = 0; | ||||||
|  | end | ||||||
|  | if min == 60 | ||||||
|  |     int_deg = int_deg + 1; | ||||||
|  |     min     = 0; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %%% Construct the output | ||||||
|  | dmsOutput = int_deg * 100 + min + sec/100; | ||||||
|  |  | ||||||
|  | %%% Correct the sign | ||||||
|  | if neg_arg == true | ||||||
|  |     dmsOutput = -dmsOutput; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%% end deg2dms.m %%%%%%%%%%%%%%%% | ||||||
							
								
								
									
										12
									
								
								src/utils/matlab/libs/geoFunctions/dms2deg.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/utils/matlab/libs/geoFunctions/dms2deg.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  |  | ||||||
|  | function deg = dms2deg(dms) | ||||||
|  | %DMS2DEG  Conversion of  degrees, minutes, and seconds to degrees. | ||||||
|  |  | ||||||
|  | % Written by Javier Arribas 2011 | ||||||
|  | % December 7, 2011 | ||||||
|  |  | ||||||
|  | %if (dms(1)>=0) | ||||||
|  |     deg=dms(1)+dms(2)/60+dms(3)/3600; | ||||||
|  | %else | ||||||
|  |     %deg=dms(1)-dms(2)/60-dms(3)/3600; | ||||||
|  | %end | ||||||
							
								
								
									
										104
									
								
								src/utils/matlab/libs/geoFunctions/dms2mat.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								src/utils/matlab/libs/geoFunctions/dms2mat.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | |||||||
|  | function [dout,mout,sout] = dms2mat(dms,n) | ||||||
|  |  | ||||||
|  | %DMS2MAT Converts a dms vector format to a [deg min sec] matrix | ||||||
|  | % | ||||||
|  | %  [d,m,s] = DMS2MAT(dms) converts a dms vector format to a | ||||||
|  | %  deg:min:sec matrix.  The vector format is dms = 100*deg + min + sec/100. | ||||||
|  | %  This allows compressed dms data to be expanded to a d,m,s triple, | ||||||
|  | %  for easier reporting and viewing of the data. | ||||||
|  | % | ||||||
|  | %  [d,m,s] = DMS2MAT(dms,n) uses n digits in the accuracy of the | ||||||
|  | %  seconds calculation.  n = -2 uses accuracy in the hundredths position, | ||||||
|  | %  n = 0 uses accuracy in the units position.  Default is n = -5. | ||||||
|  | %  For further discussion of the input n, see ROUNDN. | ||||||
|  | % | ||||||
|  | %  mat = DMS2MAT(...) returns a single output argument of mat = [d m s]. | ||||||
|  | %  This is useful only if the input dms is a single column vector. | ||||||
|  | % | ||||||
|  | %  See also MAT2DMS | ||||||
|  |  | ||||||
|  | %  Copyright 1996-2002 Systems Planning and Analysis, Inc. and The MathWorks, Inc. | ||||||
|  | %  Written by:  E. Byrns, E. Brown | ||||||
|  | %   $Revision: 1.10 $    $Date: 2002/03/20 21:25:06 $ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | if nargin == 0 | ||||||
|  |     error('Incorrect number of arguments') | ||||||
|  | elseif nargin == 1 | ||||||
|  |     n = -5; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %  Test for empty arguments | ||||||
|  |  | ||||||
|  | if isempty(dms); dout = []; mout = []; sout = []; return; end | ||||||
|  |  | ||||||
|  | %  Test for complex arguments | ||||||
|  |  | ||||||
|  | if ~isreal(dms) | ||||||
|  |     warning('Imaginary parts of complex ANGLE argument ignored') | ||||||
|  |     dms = real(dms); | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %  Don't let seconds be rounded beyond the tens place. | ||||||
|  | %  If you did, then 55 seconds rounds to 100, which is not good. | ||||||
|  |  | ||||||
|  | if n == 2;  n = 1;   end | ||||||
|  |  | ||||||
|  | %  Construct a sign vector which has +1 when dms >= 0 and -1 when dms < 0. | ||||||
|  |  | ||||||
|  | signvec = sign(dms); | ||||||
|  | signvec = signvec + (signvec == 0);   %  Ensure +1 when dms = 0 | ||||||
|  |  | ||||||
|  | %  Decompress the dms data vector | ||||||
|  |  | ||||||
|  | dms = abs(dms); | ||||||
|  | d = fix(dms/100);                      %  Degrees | ||||||
|  | m = fix(dms) - abs(100*d);             %  Minutes | ||||||
|  | [s,msg] = roundn(100*rem(dms,1),n);    %  Seconds:  Truncate to roundoff error | ||||||
|  | if ~isempty(msg);   error(msg);   end | ||||||
|  |  | ||||||
|  | %  Adjust for 60 seconds or 60 minutes. | ||||||
|  | %  Test for seconds > 60 to allow for round-off from roundn, | ||||||
|  | %  Test for minutes > 60 as a ripple effect from seconds > 60 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | indx = find(s >= 60); | ||||||
|  | if ~isempty(indx);   m(indx) = m(indx) + 1;   s(indx) = s(indx) - 60;   end | ||||||
|  | indx = find(m >= 60); | ||||||
|  | if ~isempty(indx);   d(indx) = d(indx) + 1;   m(indx) =  m(indx) - 60;   end | ||||||
|  |  | ||||||
|  | %  Data consistency checks | ||||||
|  |  | ||||||
|  | if any(m > 59) | any (m < 0) | ||||||
|  |     error('Minutes must be >= 0 and <= 59') | ||||||
|  |  | ||||||
|  | elseif any(s >= 60) | any( s < 0) | ||||||
|  |     error('Seconds must be >= 0 and < 60') | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %  Determine where to store the sign of the angle.  It should be | ||||||
|  | %  associated with the largest nonzero component of d:m:s. | ||||||
|  |  | ||||||
|  | dsign = signvec .* (d~=0); | ||||||
|  | msign = signvec .* (d==0 & m~=0); | ||||||
|  | ssign = signvec .* (d==0 & m==0 & s~=0); | ||||||
|  |  | ||||||
|  | %  In the application of signs below, the comparison with 0 is used so that | ||||||
|  | %  the sign vector contains only +1 and -1.  Any zero occurances causes | ||||||
|  | %  data to be lost when the sign has been applied to a higher component | ||||||
|  | %  of d:m:s.  Use fix function to eliminate potential round-off errors. | ||||||
|  |  | ||||||
|  | d = ((dsign==0) + dsign).*fix(d);      %  Apply signs to the degrees | ||||||
|  | m = ((msign==0) + msign).*fix(m);      %  Apply signs to minutes | ||||||
|  | s = ((ssign==0) + ssign).*s;           %  Apply signs to seconds | ||||||
|  |  | ||||||
|  | %  Set the output arguments | ||||||
|  |  | ||||||
|  | if nargout <= 1 | ||||||
|  |     dout = [d m s]; | ||||||
|  | elseif nargout == 3 | ||||||
|  |     dout = d;   mout = m;   sout = s; | ||||||
|  | else | ||||||
|  |     error('Invalid number of output arguments') | ||||||
|  | end | ||||||
|  |  | ||||||
							
								
								
									
										34
									
								
								src/utils/matlab/libs/geoFunctions/e_r_corr.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/utils/matlab/libs/geoFunctions/e_r_corr.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | function X_sat_rot = e_r_corr(traveltime, X_sat) | ||||||
|  | %E_R_CORR  Returns rotated satellite ECEF coordinates due to Earth | ||||||
|  | %rotation during signal travel time | ||||||
|  | % | ||||||
|  | %X_sat_rot = e_r_corr(traveltime, X_sat); | ||||||
|  | % | ||||||
|  | %   Inputs: | ||||||
|  | %       travelTime  - signal travel time | ||||||
|  | %       X_sat       - satellite's ECEF coordinates | ||||||
|  | % | ||||||
|  | %   Outputs: | ||||||
|  | %       X_sat_rot   - rotated satellite's coordinates (ECEF) | ||||||
|  |  | ||||||
|  | %Written by Kai Borre | ||||||
|  | %Copyright (c) by Kai Borre | ||||||
|  | % | ||||||
|  | % CVS record: | ||||||
|  | % $Id: e_r_corr.m,v 1.1.1.1.2.6 2006/08/22 13:45:59 dpl Exp $ | ||||||
|  | %========================================================================== | ||||||
|  |  | ||||||
|  | Omegae_dot = 7.292115147e-5;           %  rad/sec | ||||||
|  |  | ||||||
|  | %--- Find rotation angle -------------------------------------------------- | ||||||
|  | omegatau   = Omegae_dot * traveltime; | ||||||
|  |  | ||||||
|  | %--- Make a rotation matrix ----------------------------------------------- | ||||||
|  | R3 = [ cos(omegatau)    sin(omegatau)   0; | ||||||
|  |       -sin(omegatau)    cos(omegatau)   0; | ||||||
|  |        0                0               1]; | ||||||
|  |  | ||||||
|  | %--- Do the rotation ------------------------------------------------------ | ||||||
|  | X_sat_rot = R3 * X_sat; | ||||||
|  |  | ||||||
|  | %%%%%%%% end e_r_corr.m %%%%%%%%%%%%%%%%%%%% | ||||||
							
								
								
									
										72
									
								
								src/utils/matlab/libs/geoFunctions/findUtmZone.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/utils/matlab/libs/geoFunctions/findUtmZone.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | function utmZone = findUtmZone(latitude, longitude) | ||||||
|  | %Function finds the UTM zone number for given longitude and latitude. | ||||||
|  | %The longitude value must be between -180 (180 degree West) and 180 (180 | ||||||
|  | %degree East) degree. The latitude must be within -80 (80 degree South) and | ||||||
|  | %84 (84 degree North). | ||||||
|  | % | ||||||
|  | %utmZone = findUtmZone(latitude, longitude); | ||||||
|  | % | ||||||
|  | %Latitude and longitude must be in decimal degrees (e.g. 15.5 degrees not | ||||||
|  | %15 deg 30 min).  | ||||||
|  |  | ||||||
|  | %-------------------------------------------------------------------------- | ||||||
|  | %                           SoftGNSS v3.0 | ||||||
|  | %  | ||||||
|  | % Copyright (C) Darius Plausinaitis | ||||||
|  | % Written by Darius Plausinaitis | ||||||
|  | %-------------------------------------------------------------------------- | ||||||
|  | %This program is free software; you can redistribute it and/or | ||||||
|  | %modify it under the terms of the GNU General Public License | ||||||
|  | %as published by the Free Software Foundation; either version 2 | ||||||
|  | %of the License, or (at your option) any later version. | ||||||
|  | % | ||||||
|  | %This program is distributed in the hope that it will be useful, | ||||||
|  | %but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | %MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | %GNU General Public License for more details. | ||||||
|  | % | ||||||
|  | %You should have received a copy of the GNU General Public License | ||||||
|  | %along with this program; if not, write to the Free Software | ||||||
|  | %Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, | ||||||
|  | %USA. | ||||||
|  | %========================================================================== | ||||||
|  |  | ||||||
|  | %CVS record: | ||||||
|  | %$Id: findUtmZone.m,v 1.1.2.2 2006/08/22 13:45:59 dpl Exp $ | ||||||
|  |  | ||||||
|  | %% Check value bounds ===================================================== | ||||||
|  |  | ||||||
|  | if ((longitude > 180) || (longitude < -180)) | ||||||
|  |     error('Longitude value exceeds limits (-180:180).'); | ||||||
|  | end | ||||||
|  |  | ||||||
|  | if ((latitude > 84) || (latitude < -80)) | ||||||
|  |     error('Latitude value exceeds limits (-80:84).'); | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %% Find zone ============================================================== | ||||||
|  |  | ||||||
|  | % Start at 180 deg west = -180 deg | ||||||
|  |  | ||||||
|  | utmZone = fix((180 + longitude)/ 6) + 1; | ||||||
|  |  | ||||||
|  | %% Correct zone numbers for particular areas ============================== | ||||||
|  |  | ||||||
|  | if (latitude > 72) | ||||||
|  |     % Corrections for zones 31 33 35 37 | ||||||
|  |     if ((longitude >= 0) && (longitude < 9)) | ||||||
|  |         utmZone = 31; | ||||||
|  |     elseif ((longitude >= 9) && (longitude < 21)) | ||||||
|  |         utmZone = 33; | ||||||
|  |     elseif ((longitude >= 21) && (longitude < 33)) | ||||||
|  |         utmZone = 35; | ||||||
|  |     elseif ((longitude >= 33) && (longitude < 42)) | ||||||
|  |         utmZone = 37; | ||||||
|  |     end     | ||||||
|  |      | ||||||
|  | elseif ((latitude >= 56) && (latitude < 64)) | ||||||
|  |     % Correction for zone 32 | ||||||
|  |     if ((longitude >= 3) && (longitude < 12)) | ||||||
|  |         utmZone = 32; | ||||||
|  |     end | ||||||
|  | end | ||||||
							
								
								
									
										48
									
								
								src/utils/matlab/libs/geoFunctions/geo2cart.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/utils/matlab/libs/geoFunctions/geo2cart.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | function [X, Y, Z] = geo2cart(phi, lambda, h, i) | ||||||
|  | %GEO2CART Conversion of geographical coordinates (phi, lambda, h) to | ||||||
|  | %Cartesian coordinates (X, Y, Z).  | ||||||
|  | % | ||||||
|  | %[X, Y, Z] = geo2cart(phi, lambda, h, i); | ||||||
|  | % | ||||||
|  | %Format for phi and lambda: [degrees minutes seconds]. | ||||||
|  | %h, X, Y, and Z are in meters. | ||||||
|  | % | ||||||
|  | %Choices i of Reference Ellipsoid | ||||||
|  | %   1. International Ellipsoid 1924 | ||||||
|  | %   2. International Ellipsoid 1967 | ||||||
|  | %   3. World Geodetic System 1972 | ||||||
|  | %   4. Geodetic Reference System 1980 | ||||||
|  | %   5. World Geodetic System 1984 | ||||||
|  | % | ||||||
|  | %   Inputs: | ||||||
|  | %       phi       - geocentric latitude (format [degrees minutes seconds]) | ||||||
|  | %       lambda    - geocentric longitude (format [degrees minutes seconds])  | ||||||
|  | %       h         - height | ||||||
|  | %       i         - reference ellipsoid type | ||||||
|  | % | ||||||
|  | %   Outputs: | ||||||
|  | %       X, Y, Z   - Cartesian coordinates (meters) | ||||||
|  |  | ||||||
|  | %Kai Borre 10-13-98 | ||||||
|  | %Copyright (c) by Kai Borre | ||||||
|  | % | ||||||
|  | % CVS record: | ||||||
|  | % $Id: geo2cart.m,v 1.1.2.7 2006/08/22 13:45:59 dpl Exp $ | ||||||
|  | %========================================================================== | ||||||
|  |  | ||||||
|  | b   = phi(1) + phi(2)/60 + phi(3)/3600; | ||||||
|  | b   = b*pi / 180; | ||||||
|  | l   = lambda(1) + lambda(2)/60 + lambda(3)/3600; | ||||||
|  | l   = l*pi / 180; | ||||||
|  |  | ||||||
|  | a   = [6378388 6378160 6378135 6378137 6378137]; | ||||||
|  | f   = [1/297 1/298.247 1/298.26 1/298.257222101 1/298.257223563]; | ||||||
|  |  | ||||||
|  | ex2 = (2-f(i))*f(i) / ((1-f(i))^2); | ||||||
|  | c   = a(i) * sqrt(1+ex2); | ||||||
|  | N   = c / sqrt(1 + ex2*cos(b)^2); | ||||||
|  |  | ||||||
|  | X   = (N+h) * cos(b) * cos(l); | ||||||
|  | Y   = (N+h) * cos(b) * sin(l); | ||||||
|  | Z   = ((1-f(i))^2*N + h) * sin(b); | ||||||
|  | %%%%%%%%%%%%%% end geo2cart.m  %%%%%%%%%%%%%%%%%%%%%%%% | ||||||
							
								
								
									
										114
									
								
								src/utils/matlab/libs/geoFunctions/leastSquarePos.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/utils/matlab/libs/geoFunctions/leastSquarePos.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | |||||||
|  | function [pos, el, az, dop] = leastSquarePos(satpos, obs, settings) | ||||||
|  | %Function calculates the Least Square Solution. | ||||||
|  | % | ||||||
|  | %[pos, el, az, dop] = leastSquarePos(satpos, obs, settings); | ||||||
|  | % | ||||||
|  | %   Inputs: | ||||||
|  | %       satpos      - Satellites positions (in ECEF system: [X; Y; Z;] - | ||||||
|  | %                   one column per satellite) | ||||||
|  | %       obs         - Observations - the pseudorange measurements to each | ||||||
|  | %                   satellite: | ||||||
|  | %                   (e.g. [20000000 21000000 .... .... .... .... ....]) | ||||||
|  | %       settings    - receiver settings | ||||||
|  | % | ||||||
|  | %   Outputs: | ||||||
|  | %       pos         - receiver position and receiver clock error  | ||||||
|  | %                   (in ECEF system: [X, Y, Z, dt])  | ||||||
|  | %       el          - Satellites elevation angles (degrees) | ||||||
|  | %       az          - Satellites azimuth angles (degrees) | ||||||
|  | %       dop         - Dilutions Of Precision ([GDOP PDOP HDOP VDOP TDOP]) | ||||||
|  |  | ||||||
|  | %-------------------------------------------------------------------------- | ||||||
|  | %                           SoftGNSS v3.0 | ||||||
|  | %-------------------------------------------------------------------------- | ||||||
|  | %Based on Kai Borre | ||||||
|  | %Copyright (c) by Kai Borre | ||||||
|  | %Updated by Darius Plausinaitis, Peter Rinder and Nicolaj Bertelsen | ||||||
|  | % | ||||||
|  | % CVS record: | ||||||
|  | % $Id: leastSquarePos.m,v 1.1.2.12 2006/08/22 13:45:59 dpl Exp $ | ||||||
|  | %========================================================================== | ||||||
|  |  | ||||||
|  | %=== Initialization ======================================================= | ||||||
|  | nmbOfIterations = 7; | ||||||
|  |  | ||||||
|  | dtr     = pi/180; | ||||||
|  | pos     = zeros(4, 1); | ||||||
|  | X       = satpos; | ||||||
|  | nmbOfSatellites = size(satpos, 2); | ||||||
|  |  | ||||||
|  | A       = zeros(nmbOfSatellites, 4); | ||||||
|  | omc     = zeros(nmbOfSatellites, 1); | ||||||
|  | az      = zeros(1, nmbOfSatellites); | ||||||
|  | el      = az; | ||||||
|  |  | ||||||
|  | %=== Iteratively find receiver position =================================== | ||||||
|  | for iter = 1:nmbOfIterations | ||||||
|  |  | ||||||
|  |     for i = 1:nmbOfSatellites | ||||||
|  |         if iter == 1 | ||||||
|  |             %--- Initialize variables at the first iteration -------------- | ||||||
|  |             Rot_X = X(:, i); | ||||||
|  |             trop = 2; | ||||||
|  |         else | ||||||
|  |             %--- Update equations ----------------------------------------- | ||||||
|  |             rho2 = (X(1, i) - pos(1))^2 + (X(2, i) - pos(2))^2 + ... | ||||||
|  |                    (X(3, i) - pos(3))^2; | ||||||
|  |             traveltime = sqrt(rho2) / settings.c ; | ||||||
|  |  | ||||||
|  |             %--- Correct satellite position (do to earth rotation) -------- | ||||||
|  |             Rot_X = e_r_corr(traveltime, X(:, i)); | ||||||
|  |  | ||||||
|  |             %--- Find the elevation angel of the satellite ---------------- | ||||||
|  |             [az(i), el(i), dist] = topocent(pos(1:3, :), Rot_X - pos(1:3, :)); | ||||||
|  |  | ||||||
|  |             if (settings.useTropCorr == 1) | ||||||
|  |                 %--- Calculate tropospheric correction -------------------- | ||||||
|  |                 trop = tropo(sin(el(i) * dtr), ... | ||||||
|  |                              0.0, 1013.0, 293.0, 50.0, 0.0, 0.0, 0.0); | ||||||
|  |             else | ||||||
|  |                 % Do not calculate or apply the tropospheric corrections | ||||||
|  |                 trop = 0; | ||||||
|  |             end | ||||||
|  |         end % if iter == 1 ... ... else  | ||||||
|  |  | ||||||
|  |         %--- Apply the corrections ---------------------------------------- | ||||||
|  |         omc(i) = (obs(i) - norm(Rot_X - pos(1:3), 'fro') - pos(4) - trop); | ||||||
|  |  | ||||||
|  |         %--- Construct the A matrix --------------------------------------- | ||||||
|  |         A(i, :) =  [ (-(Rot_X(1) - pos(1))) / obs(i) ... | ||||||
|  |                      (-(Rot_X(2) - pos(2))) / obs(i) ... | ||||||
|  |                      (-(Rot_X(3) - pos(3))) / obs(i) ... | ||||||
|  |                      1 ]; | ||||||
|  |     end % for i = 1:nmbOfSatellites | ||||||
|  |  | ||||||
|  |     % These lines allow the code to exit gracefully in case of any errors | ||||||
|  |     if rank(A) ~= 4 | ||||||
|  |         pos     = zeros(1, 4); | ||||||
|  |         return | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     %--- Find position update --------------------------------------------- | ||||||
|  |     x   = A \ omc; | ||||||
|  |      | ||||||
|  |     %--- Apply position update -------------------------------------------- | ||||||
|  |     pos = pos + x; | ||||||
|  |      | ||||||
|  | end % for iter = 1:nmbOfIterations | ||||||
|  |  | ||||||
|  | pos = pos'; | ||||||
|  |  | ||||||
|  | %=== Calculate Dilution Of Precision ====================================== | ||||||
|  | if nargout  == 4 | ||||||
|  |     %--- Initialize output ------------------------------------------------ | ||||||
|  |     dop     = zeros(1, 5); | ||||||
|  |      | ||||||
|  |     %--- Calculate DOP ---------------------------------------------------- | ||||||
|  |     Q       = inv(A'*A); | ||||||
|  |      | ||||||
|  |     dop(1)  = sqrt(trace(Q));                       % GDOP     | ||||||
|  |     dop(2)  = sqrt(Q(1,1) + Q(2,2) + Q(3,3));       % PDOP | ||||||
|  |     dop(3)  = sqrt(Q(1,1) + Q(2,2));                % HDOP | ||||||
|  |     dop(4)  = sqrt(Q(3,3));                         % VDOP | ||||||
|  |     dop(5)  = sqrt(Q(4,4));                         % TDOP | ||||||
|  | end | ||||||
							
								
								
									
										125
									
								
								src/utils/matlab/libs/geoFunctions/mat2dms.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								src/utils/matlab/libs/geoFunctions/mat2dms.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | |||||||
|  | function dmsvec = mat2dms(d,m,s,n) | ||||||
|  |  | ||||||
|  | %MAT2DMS Converts a [deg min sec] matrix to vector format | ||||||
|  | % | ||||||
|  | %  dms = MAT2DMS(d,m,s) converts a deg:min:sec matrix into a vector | ||||||
|  | %  format.  The vector format is dms = 100*deg + min + sec/100. | ||||||
|  | %  This allows d,m,s triple to be compressed into a single value, | ||||||
|  | %  which can then be employed similar to a degree or radian vector. | ||||||
|  | %  The inputs d, m and s must be of equal size.  Minutes and | ||||||
|  | %  second must be between 0 and 60. | ||||||
|  | % | ||||||
|  | %  dms = MAT2DMS(mat) assumes and input matrix of [d m s].  This is | ||||||
|  | %  useful only for single column vectors for d, m and s. | ||||||
|  | % | ||||||
|  | %  dms = MAT2DMS(d,m) and dms = MAT2DMS([d m]) assume that seconds | ||||||
|  | %  are zero, s = 0. | ||||||
|  | % | ||||||
|  | %  dms = MAT2DMS(d,m,s,n) uses n as the accuracy of the seconds | ||||||
|  | %  calculation.  n = -2 uses accuracy in the hundredths position, | ||||||
|  | %  n = 0 uses accuracy in the units position.  Default is n = -5. | ||||||
|  | %  For further discussion of the input n, see ROUNDN. | ||||||
|  | % | ||||||
|  | %  See also DMS2MAT | ||||||
|  |  | ||||||
|  | %  Copyright 1996-2002 Systems Planning and Analysis, Inc. and The MathWorks, Inc. | ||||||
|  | %  Written by:  E. Byrns, E. Brown | ||||||
|  | %   $Revision: 1.10 $    $Date: 2002/03/20 21:25:51 $ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | if nargin == 0 | ||||||
|  |     error('Incorrect number of arguments') | ||||||
|  |  | ||||||
|  | elseif nargin==1 | ||||||
|  |     if size(d,2)== 3 | ||||||
|  |         s = d(:,3);   m = d(:,2);   d = d(:,1); | ||||||
|  |     elseif size(d,2)== 2 | ||||||
|  |         m = d(:,2);   d = d(:,1);   s = zeros(size(d)); | ||||||
|  |     elseif size(d,2) == 0 | ||||||
|  |         d = [];   m = [];   s = []; | ||||||
|  |     else | ||||||
|  |         error('Single input matrices must be n-by-2 or n-by-3.'); | ||||||
|  |     end | ||||||
|  |     n = -5; | ||||||
|  |  | ||||||
|  | elseif nargin == 2 | ||||||
|  |     s = zeros(size(d)); | ||||||
|  |     n = -5; | ||||||
|  |  | ||||||
|  | elseif nargin == 3 | ||||||
|  |     n = -5; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %  Test for empty arguments | ||||||
|  |  | ||||||
|  | if isempty(d) & isempty(m) & isempty(s);  dmsvec = [];  return;  end | ||||||
|  |  | ||||||
|  | %  Don't let seconds be rounded beyond the tens place. | ||||||
|  | %  If you did, then 55 seconds rounds to 100, which is not good. | ||||||
|  |  | ||||||
|  | if n == 2;  n = 1;   end | ||||||
|  |  | ||||||
|  | %  Complex argument tests | ||||||
|  |  | ||||||
|  | if any([~isreal(d) ~isreal(m) ~isreal(s)]) | ||||||
|  |     warning('Imaginary parts of complex ANGLE argument ignored') | ||||||
|  |     d = real(d);   m = real(m);   s = real(s); | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %  Dimension and value tests | ||||||
|  |  | ||||||
|  | if ~isequal(size(d),size(m),size(s)) | ||||||
|  |     error('Inconsistent dimensions for input arguments') | ||||||
|  | elseif any(rem(d(~isnan(d)),1) ~= 0 | rem(m(~isnan(m)),1) ~= 0) | ||||||
|  |     error('Degrees and minutes must be integers') | ||||||
|  | end | ||||||
|  |  | ||||||
|  | if any(abs(m) > 60) | any (abs(m) < 0)       %  Actually algorithm allows for | ||||||
|  |     error('Minutes must be >= 0 and < 60')   %  up to exactly 60 seconds or | ||||||
|  |     %  60 minutes, but the error message | ||||||
|  | elseif any(abs(s) > 60) | any(abs(s) < 0)    %  doesn't reflect this so that angst | ||||||
|  |     error('Seconds must be >= 0 and < 60')   %  is minimized in the user docs | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %  Ensure that only one negative sign is present and at the correct location | ||||||
|  |  | ||||||
|  | if any((s<0 & m<0) | (s<0 & d<0) | (m<0 & d<0) ) | ||||||
|  |     error('Multiple negative entries in a DMS specification') | ||||||
|  | elseif any((s<0 & (m~=0 | d~= 0)) | (m<0 & d~=0)) | ||||||
|  |     error('Incorrect negative DMS specification') | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %  Construct a sign vector which has +1 when | ||||||
|  | %  angle >= 0 and -1 when angle < 0.  Note that the sign of the | ||||||
|  | %  angle is associated with the largest nonzero component of d:m:s | ||||||
|  |  | ||||||
|  | negvec = (d<0) | (m<0) | (s<0); | ||||||
|  | signvec = ~negvec - negvec; | ||||||
|  |  | ||||||
|  | %  Convert to all positive numbers.  Allows for easier | ||||||
|  | %  adjusting at 60 seconds and 60 minutes | ||||||
|  |  | ||||||
|  | d = abs(d);     m = abs(m);    s = abs(s); | ||||||
|  |  | ||||||
|  | %  Truncate seconds to a specified accuracy to eliminate round-off errors | ||||||
|  |  | ||||||
|  | [s,msg] = roundn(s,n); | ||||||
|  | if ~isempty(msg);   error(msg);   end | ||||||
|  |  | ||||||
|  | %  Adjust for 60 seconds or 60 minutes. If s > 60, this can only be | ||||||
|  | %  from round-off during roundn since s > 60 is already tested above. | ||||||
|  | %  This round-off effect has happened though. | ||||||
|  |  | ||||||
|  | indx = find(s >= 60); | ||||||
|  | if ~isempty(indx);   m(indx) = m(indx) + 1;   s(indx) = 0;   end | ||||||
|  |  | ||||||
|  | %  The user can not put minutes > 60 as input.  However, the line | ||||||
|  | %  above may create minutes > 60 (since the user can put in m == 60), | ||||||
|  | %  thus, the test below includes the greater than condition. | ||||||
|  |  | ||||||
|  | indx = find(m >= 60); | ||||||
|  | if ~isempty(indx);   d(indx) = d(indx) + 1;   m(indx) = m(indx)-60;   end | ||||||
|  |  | ||||||
|  | %  Construct the dms vector format | ||||||
|  |  | ||||||
|  | dmsvec = signvec .* (100*d + m + s/100); | ||||||
							
								
								
									
										46
									
								
								src/utils/matlab/libs/geoFunctions/roundn.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/utils/matlab/libs/geoFunctions/roundn.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | function [x,msg] = roundn(x,n) | ||||||
|  |  | ||||||
|  | %ROUNDN  Rounds input data at specified power of 10 | ||||||
|  | % | ||||||
|  | %  y = ROUNDN(x) rounds the input data x to the nearest hundredth. | ||||||
|  | % | ||||||
|  | %  y = ROUNDN(x,n) rounds the input data x at the specified power | ||||||
|  | %  of tens position.  For example, n = -2 rounds the input data to | ||||||
|  | %  the 10E-2 (hundredths) position. | ||||||
|  | % | ||||||
|  | %  [y,msg] = ROUNDN(...) returns the text of any error condition | ||||||
|  | %  encountered in the output variable msg. | ||||||
|  | % | ||||||
|  | %  See also ROUND | ||||||
|  |  | ||||||
|  | %  Copyright 1996-2002 Systems Planning and Analysis, Inc. and The MathWorks, Inc. | ||||||
|  | %  Written by:  E. Byrns, E. Brown | ||||||
|  | %   $Revision: 1.9 $    $Date: 2002/03/20 21:26:19 $ | ||||||
|  |  | ||||||
|  | msg = [];   %  Initialize output | ||||||
|  |  | ||||||
|  | if nargin == 0 | ||||||
|  |     error('Incorrect number of arguments') | ||||||
|  | elseif nargin == 1 | ||||||
|  |     n = -2; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %  Test for scalar n | ||||||
|  |  | ||||||
|  | if max(size(n)) ~= 1 | ||||||
|  |     msg = 'Scalar accuracy required'; | ||||||
|  |     if nargout < 2;  error(msg);  end | ||||||
|  |     return | ||||||
|  | elseif ~isreal(n) | ||||||
|  |     warning('Imaginary part of complex N argument ignored') | ||||||
|  |     n = real(n); | ||||||
|  | end | ||||||
|  |  | ||||||
|  | %  Compute the exponential factors for rounding at specified | ||||||
|  | %  power of 10.  Ensure that n is an integer. | ||||||
|  |  | ||||||
|  | factors  = 10 ^ (fix(-n)); | ||||||
|  |  | ||||||
|  | %  Set the significant digits for the input data | ||||||
|  |  | ||||||
|  | x = round(x * factors) / factors; | ||||||
							
								
								
									
										141
									
								
								src/utils/matlab/libs/geoFunctions/satpos.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								src/utils/matlab/libs/geoFunctions/satpos.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,141 @@ | |||||||
|  | function [satPositions, satClkCorr] = satpos(transmitTime, prnList, ... | ||||||
|  |                                              eph, settings)  | ||||||
|  | %SATPOS Computation of satellite coordinates X,Y,Z at TRANSMITTIME for | ||||||
|  | %given ephemeris EPH. Coordinates are computed for each satellite in the | ||||||
|  | %list PRNLIST. | ||||||
|  | %[satPositions, satClkCorr] = satpos(transmitTime, prnList, eph, settings); | ||||||
|  | % | ||||||
|  | %   Inputs: | ||||||
|  | %       transmitTime  - transmission time | ||||||
|  | %       prnList       - list of PRN-s to be processed | ||||||
|  | %       eph           - ephemerides of satellites | ||||||
|  | %       settings      - receiver settings | ||||||
|  | % | ||||||
|  | %   Outputs: | ||||||
|  | %       satPositions  - position of satellites (in ECEF system [X; Y; Z;]) | ||||||
|  | %       satClkCorr    - correction of satellite clocks | ||||||
|  |  | ||||||
|  | %-------------------------------------------------------------------------- | ||||||
|  | %                           SoftGNSS v3.0 | ||||||
|  | %-------------------------------------------------------------------------- | ||||||
|  | %Based on Kai Borre 04-09-96 | ||||||
|  | %Copyright (c) by Kai Borre | ||||||
|  | %Updated by Darius Plausinaitis, Peter Rinder and Nicolaj Bertelsen | ||||||
|  | % | ||||||
|  | % CVS record: | ||||||
|  | % $Id: satpos.m,v 1.1.2.17 2007/01/30 09:45:12 dpl Exp $ | ||||||
|  |  | ||||||
|  | %% Initialize constants =================================================== | ||||||
|  | numOfSatellites = size(prnList, 2); | ||||||
|  |  | ||||||
|  | % GPS constatns | ||||||
|  |  | ||||||
|  | gpsPi          = 3.1415926535898;  % Pi used in the GPS coordinate  | ||||||
|  |                                    % system | ||||||
|  |  | ||||||
|  | %--- Constants for satellite position calculation ------------------------- | ||||||
|  | Omegae_dot     = 7.2921151467e-5;  % Earth rotation rate, [rad/s] | ||||||
|  | GM             = 3.986005e14;      % Universal gravitational constant times | ||||||
|  |                                    % the mass of the Earth, [m^3/s^2] | ||||||
|  | F              = -4.442807633e-10; % Constant, [sec/(meter)^(1/2)] | ||||||
|  |  | ||||||
|  | %% Initialize results ===================================================== | ||||||
|  | satClkCorr   = zeros(1, numOfSatellites); | ||||||
|  | satPositions = zeros(3, numOfSatellites); | ||||||
|  |  | ||||||
|  | %% Process each satellite ================================================= | ||||||
|  |  | ||||||
|  | for satNr = 1 : numOfSatellites | ||||||
|  |      | ||||||
|  |     prn = prnList(satNr); | ||||||
|  |      | ||||||
|  | %% Find initial satellite clock correction -------------------------------- | ||||||
|  |  | ||||||
|  |     %--- Find time difference --------------------------------------------- | ||||||
|  |     dt = check_t(transmitTime - eph(prn).t_oc); | ||||||
|  |  | ||||||
|  |     %--- Calculate clock correction --------------------------------------- | ||||||
|  |     satClkCorr(satNr) = (eph(prn).a_f2 * dt + eph(prn).a_f1) * dt + ... | ||||||
|  |                          eph(prn).a_f0 - ... | ||||||
|  |                          eph(prn).T_GD; | ||||||
|  |  | ||||||
|  |     time = transmitTime - satClkCorr(satNr); | ||||||
|  |  | ||||||
|  | %% Find satellite's position ---------------------------------------------- | ||||||
|  |  | ||||||
|  |     %Restore semi-major axis | ||||||
|  |     a   = eph(prn).sqrtA * eph(prn).sqrtA; | ||||||
|  |  | ||||||
|  |     %Time correction | ||||||
|  |     tk  = check_t(time - eph(prn).t_oe); | ||||||
|  |  | ||||||
|  |     %Initial mean motion | ||||||
|  |     n0  = sqrt(GM / a^3); | ||||||
|  |     %Mean motion | ||||||
|  |     n   = n0 + eph(prn).deltan; | ||||||
|  |  | ||||||
|  |     %Mean anomaly | ||||||
|  |     M   = eph(prn).M_0 + n * tk; | ||||||
|  |     %Reduce mean anomaly to between 0 and 360 deg | ||||||
|  |     M   = rem(M + 2*gpsPi, 2*gpsPi); | ||||||
|  |  | ||||||
|  |     %Initial guess of eccentric anomaly | ||||||
|  |     E   = M; | ||||||
|  |  | ||||||
|  |     %--- Iteratively compute eccentric anomaly ---------------------------- | ||||||
|  |     for ii = 1:10 | ||||||
|  |         E_old   = E; | ||||||
|  |         E       = M + eph(prn).e * sin(E); | ||||||
|  |         dE      = rem(E - E_old, 2*gpsPi); | ||||||
|  |  | ||||||
|  |         if abs(dE) < 1.e-12 | ||||||
|  |             % Necessary precision is reached, exit from the loop  | ||||||
|  |             break; | ||||||
|  |         end | ||||||
|  |     end  | ||||||
|  |  | ||||||
|  |     %Reduce eccentric anomaly to between 0 and 360 deg | ||||||
|  |     E   = rem(E + 2*gpsPi, 2*gpsPi); | ||||||
|  |  | ||||||
|  |     %Compute relativistic correction term | ||||||
|  |     dtr = F * eph(prn).e * eph(prn).sqrtA * sin(E); | ||||||
|  |  | ||||||
|  |     %Calculate the true anomaly | ||||||
|  |     nu   = atan2(sqrt(1 - eph(prn).e^2) * sin(E), cos(E)-eph(prn).e); | ||||||
|  |  | ||||||
|  |     %Compute angle phi | ||||||
|  |     phi = nu + eph(prn).omega; | ||||||
|  |     %Reduce phi to between 0 and 360 deg | ||||||
|  |     phi = rem(phi, 2*gpsPi); | ||||||
|  |  | ||||||
|  |     %Correct argument of latitude | ||||||
|  |     u = phi + ... | ||||||
|  |         eph(prn).C_uc * cos(2*phi) + ... | ||||||
|  |         eph(prn).C_us * sin(2*phi); | ||||||
|  |     %Correct radius | ||||||
|  |     r = a * (1 - eph(prn).e*cos(E)) + ... | ||||||
|  |         eph(prn).C_rc * cos(2*phi) + ... | ||||||
|  |         eph(prn).C_rs * sin(2*phi); | ||||||
|  |     %Correct inclination | ||||||
|  |     i = eph(prn).i_0 + eph(prn).iDot * tk + ... | ||||||
|  |         eph(prn).C_ic * cos(2*phi) + ... | ||||||
|  |         eph(prn).C_is * sin(2*phi); | ||||||
|  |  | ||||||
|  |     %Compute the angle between the ascending node and the Greenwich meridian | ||||||
|  |     Omega = eph(prn).omega_0 + (eph(prn).omegaDot - Omegae_dot)*tk - ... | ||||||
|  |             Omegae_dot * eph(prn).t_oe; | ||||||
|  |     %Reduce to between 0 and 360 deg | ||||||
|  |     Omega = rem(Omega + 2*gpsPi, 2*gpsPi); | ||||||
|  |  | ||||||
|  |     %--- Compute satellite coordinates ------------------------------------ | ||||||
|  |     satPositions(1, satNr) = cos(u)*r * cos(Omega) - sin(u)*r * cos(i)*sin(Omega); | ||||||
|  |     satPositions(2, satNr) = cos(u)*r * sin(Omega) + sin(u)*r * cos(i)*cos(Omega); | ||||||
|  |     satPositions(3, satNr) = sin(u)*r * sin(i); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% Include relativistic correction in clock correction -------------------- | ||||||
|  |     satClkCorr(satNr) = (eph(prn).a_f2 * dt + eph(prn).a_f1) * dt + ... | ||||||
|  |                          eph(prn).a_f0 - ... | ||||||
|  |                          eph(prn).T_GD + dtr; | ||||||
|  |                       | ||||||
|  | end % for satNr = 1 : numOfSatellites | ||||||
							
								
								
									
										112
									
								
								src/utils/matlab/libs/geoFunctions/togeod.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								src/utils/matlab/libs/geoFunctions/togeod.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | function [dphi, dlambda, h] = togeod(a, finv, X, Y, Z) | ||||||
|  | %TOGEOD   Subroutine to calculate geodetic coordinates latitude, longitude, | ||||||
|  | %         height given Cartesian coordinates X,Y,Z, and reference ellipsoid | ||||||
|  | %         values semi-major axis (a) and the inverse of flattening (finv). | ||||||
|  | % | ||||||
|  | %[dphi, dlambda, h] = togeod(a, finv, X, Y, Z); | ||||||
|  | % | ||||||
|  | %  The units of linear parameters X,Y,Z,a must all agree (m,km,mi,ft,..etc) | ||||||
|  | %  The output units of angular quantities will be in decimal degrees | ||||||
|  | %  (15.5 degrees not 15 deg 30 min). The output units of h will be the | ||||||
|  | %  same as the units of X,Y,Z,a. | ||||||
|  | % | ||||||
|  | %   Inputs: | ||||||
|  | %       a           - semi-major axis of the reference ellipsoid | ||||||
|  | %       finv        - inverse of flattening of the reference ellipsoid | ||||||
|  | %       X,Y,Z       - Cartesian coordinates | ||||||
|  | % | ||||||
|  | %   Outputs: | ||||||
|  | %       dphi        - latitude | ||||||
|  | %       dlambda     - longitude | ||||||
|  | %       h           - height above reference ellipsoid | ||||||
|  |  | ||||||
|  | %  Copyright (C) 1987 C. Goad, Columbus, Ohio | ||||||
|  | %  Reprinted with permission of author, 1996 | ||||||
|  | %  Fortran code translated into MATLAB | ||||||
|  | %  Kai Borre 03-30-96 | ||||||
|  | % | ||||||
|  | % CVS record: | ||||||
|  | % $Id: togeod.m,v 1.1.1.1.2.4 2006/08/22 13:45:59 dpl Exp $ | ||||||
|  | %========================================================================== | ||||||
|  |  | ||||||
|  | h       = 0; | ||||||
|  | tolsq   = 1.e-10; | ||||||
|  | maxit   = 10; | ||||||
|  |  | ||||||
|  | % compute radians-to-degree factor | ||||||
|  | rtd     = 180/pi; | ||||||
|  |  | ||||||
|  | % compute square of eccentricity | ||||||
|  | if finv < 1.e-20 | ||||||
|  |     esq = 0; | ||||||
|  | else | ||||||
|  |     esq = (2 - 1/finv) / finv; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | oneesq  = 1 - esq; | ||||||
|  |  | ||||||
|  | % first guess | ||||||
|  | % P is distance from spin axis | ||||||
|  | P = sqrt(X^2+Y^2); | ||||||
|  | % direct calculation of longitude | ||||||
|  |  | ||||||
|  | if P > 1.e-20 | ||||||
|  |     dlambda = atan2(Y,X) * rtd; | ||||||
|  | else | ||||||
|  |     dlambda = 0; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | if (dlambda < 0) | ||||||
|  |     dlambda = dlambda + 360; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | % r is distance from origin (0,0,0) | ||||||
|  | r = sqrt(P^2 + Z^2); | ||||||
|  |  | ||||||
|  | if r > 1.e-20 | ||||||
|  |     sinphi = Z/r; | ||||||
|  | else | ||||||
|  |     sinphi = 0; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | dphi = asin(sinphi); | ||||||
|  |  | ||||||
|  | % initial value of height  =  distance from origin minus | ||||||
|  | % approximate distance from origin to surface of ellipsoid | ||||||
|  | if r < 1.e-20 | ||||||
|  |     h = 0; | ||||||
|  |     return | ||||||
|  | end | ||||||
|  |  | ||||||
|  | h = r - a*(1-sinphi*sinphi/finv); | ||||||
|  |  | ||||||
|  | % iterate | ||||||
|  | for i = 1:maxit | ||||||
|  |     sinphi  = sin(dphi); | ||||||
|  |     cosphi  = cos(dphi); | ||||||
|  |      | ||||||
|  |     % compute radius of curvature in prime vertical direction | ||||||
|  |     N_phi   = a/sqrt(1-esq*sinphi*sinphi); | ||||||
|  |      | ||||||
|  |     % compute residuals in P and Z | ||||||
|  |     dP      = P - (N_phi + h) * cosphi; | ||||||
|  |     dZ      = Z - (N_phi*oneesq + h) * sinphi; | ||||||
|  |      | ||||||
|  |     % update height and latitude | ||||||
|  |     h       = h + (sinphi*dZ + cosphi*dP); | ||||||
|  |     dphi    = dphi + (cosphi*dZ - sinphi*dP)/(N_phi + h); | ||||||
|  |      | ||||||
|  |     % test for convergence | ||||||
|  |     if (dP*dP + dZ*dZ < tolsq) | ||||||
|  |         break; | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     % Not Converged--Warn user | ||||||
|  |     if i == maxit | ||||||
|  |         fprintf([' Problem in TOGEOD, did not converge in %2.0f',... | ||||||
|  |             ' iterations\n'], i); | ||||||
|  |     end | ||||||
|  | end % for i = 1:maxit | ||||||
|  |  | ||||||
|  | dphi = dphi * rtd; | ||||||
|  | %%%%%%%% end togeod.m  %%%%%%%%%%%%%%%%%%%%%% | ||||||
							
								
								
									
										57
									
								
								src/utils/matlab/libs/geoFunctions/topocent.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/utils/matlab/libs/geoFunctions/topocent.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | function [Az, El, D] = topocent(X, dx) | ||||||
|  | %TOPOCENT  Transformation of vector dx into topocentric coordinate | ||||||
|  | %          system with origin at X. | ||||||
|  | %          Both parameters are 3 by 1 vectors. | ||||||
|  | % | ||||||
|  | %[Az, El, D] = topocent(X, dx); | ||||||
|  | % | ||||||
|  | %   Inputs: | ||||||
|  | %       X           - vector origin corrdinates (in ECEF system [X; Y; Z;])  | ||||||
|  | %       dx          - vector ([dX; dY; dZ;]).  | ||||||
|  | % | ||||||
|  | %   Outputs: | ||||||
|  | %       D           - vector length. Units like units of the input | ||||||
|  | %       Az          - azimuth from north positive clockwise, degrees | ||||||
|  | %       El          - elevation angle, degrees | ||||||
|  |  | ||||||
|  | %Kai Borre 11-24-96 | ||||||
|  | %Copyright (c) by Kai Borre | ||||||
|  | % | ||||||
|  | % CVS record: | ||||||
|  | % $Id: topocent.m,v 1.1.1.1.2.4 2006/08/22 13:45:59 dpl Exp $ | ||||||
|  | %========================================================================== | ||||||
|  |  | ||||||
|  | dtr = pi/180; | ||||||
|  |  | ||||||
|  | [phi, lambda, h] = togeod(6378137, 298.257223563, X(1), X(2), X(3)); | ||||||
|  |  | ||||||
|  | cl  = cos(lambda * dtr); | ||||||
|  | sl  = sin(lambda * dtr); | ||||||
|  | cb  = cos(phi * dtr);  | ||||||
|  | sb  = sin(phi * dtr); | ||||||
|  |  | ||||||
|  | F   = [-sl -sb*cl cb*cl; | ||||||
|  |         cl -sb*sl cb*sl; | ||||||
|  |         0    cb   sb]; | ||||||
|  |  | ||||||
|  | local_vector = F' * dx; | ||||||
|  | E   = local_vector(1); | ||||||
|  | N   = local_vector(2); | ||||||
|  | U   = local_vector(3); | ||||||
|  |  | ||||||
|  | hor_dis = sqrt(E^2 + N^2); | ||||||
|  |  | ||||||
|  | if hor_dis < 1.e-20 | ||||||
|  |     Az = 0; | ||||||
|  |     El = 90; | ||||||
|  | else | ||||||
|  |     Az = atan2(E, N)/dtr; | ||||||
|  |     El = atan2(U, hor_dis)/dtr; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | if Az < 0 | ||||||
|  |     Az = Az + 360; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | D   = sqrt(dx(1)^2 + dx(2)^2 + dx(3)^2); | ||||||
|  | %%%%%%%%% end topocent.m %%%%%%%%% | ||||||
							
								
								
									
										98
									
								
								src/utils/matlab/libs/geoFunctions/tropo.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								src/utils/matlab/libs/geoFunctions/tropo.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | |||||||
|  | function ddr = tropo(sinel, hsta, p, tkel, hum, hp, htkel, hhum) | ||||||
|  | %TROPO  Calculation of tropospheric correction. | ||||||
|  | %       The range correction ddr in m is to be subtracted from | ||||||
|  | %       pseudo-ranges and carrier phases | ||||||
|  | % | ||||||
|  | %ddr = tropo(sinel, hsta, p, tkel, hum, hp, htkel, hhum); | ||||||
|  | % | ||||||
|  | %   Inputs: | ||||||
|  | %       sinel   - sin of elevation angle of satellite | ||||||
|  | %       hsta    - height of station in km | ||||||
|  | %       p       - atmospheric pressure in mb at height hp | ||||||
|  | %       tkel    - surface temperature in degrees Kelvin at height htkel | ||||||
|  | %       hum     - humidity in % at height hhum | ||||||
|  | %       hp      - height of pressure measurement in km | ||||||
|  | %       htkel   - height of temperature measurement in km | ||||||
|  | %       hhum    - height of humidity measurement in km | ||||||
|  | % | ||||||
|  | %   Outputs: | ||||||
|  | %       ddr     - range correction (meters) | ||||||
|  | % | ||||||
|  | % Reference | ||||||
|  | % Goad, C.C. & Goodman, L. (1974) A Modified Tropospheric | ||||||
|  | % Refraction Correction Model. Paper presented at the | ||||||
|  | % American Geophysical Union Annual Fall Meeting, San | ||||||
|  | % Francisco, December 12-17 | ||||||
|  |  | ||||||
|  | % A Matlab reimplementation of a C code from driver. | ||||||
|  | % Kai Borre 06-28-95 | ||||||
|  | % | ||||||
|  | % CVS record: | ||||||
|  | % $Id: tropo.m,v 1.1.1.1.2.4 2006/08/22 13:46:00 dpl Exp $ | ||||||
|  | %========================================================================== | ||||||
|  |  | ||||||
|  | a_e    = 6378.137;     % semi-major axis of earth ellipsoid | ||||||
|  | b0     = 7.839257e-5; | ||||||
|  | tlapse = -6.5; | ||||||
|  | tkhum  = tkel + tlapse*(hhum-htkel); | ||||||
|  | atkel  = 7.5*(tkhum-273.15) / (237.3+tkhum-273.15); | ||||||
|  | e0     = 0.0611 * hum * 10^atkel; | ||||||
|  | tksea  = tkel - tlapse*htkel; | ||||||
|  | em     = -978.77 / (2.8704e6*tlapse*1.0e-5); | ||||||
|  | tkelh  = tksea + tlapse*hhum; | ||||||
|  | e0sea  = e0 * (tksea/tkelh)^(4*em); | ||||||
|  | tkelp  = tksea + tlapse*hp; | ||||||
|  | psea   = p * (tksea/tkelp)^em; | ||||||
|  |  | ||||||
|  | if sinel < 0 | ||||||
|  |     sinel = 0; | ||||||
|  | end | ||||||
|  |  | ||||||
|  | tropo   = 0; | ||||||
|  | done    = 'FALSE'; | ||||||
|  | refsea  = 77.624e-6 / tksea; | ||||||
|  | htop    = 1.1385e-5 / refsea; | ||||||
|  | refsea  = refsea * psea; | ||||||
|  | ref     = refsea * ((htop-hsta)/htop)^4; | ||||||
|  |  | ||||||
|  | while 1 | ||||||
|  |     rtop = (a_e+htop)^2 - (a_e+hsta)^2*(1-sinel^2); | ||||||
|  |      | ||||||
|  |     % check to see if geometry is crazy | ||||||
|  |     if rtop < 0 | ||||||
|  |         rtop = 0;  | ||||||
|  |     end  | ||||||
|  |      | ||||||
|  |     rtop = sqrt(rtop) - (a_e+hsta)*sinel; | ||||||
|  |     a    = -sinel/(htop-hsta); | ||||||
|  |     b    = -b0*(1-sinel^2) / (htop-hsta); | ||||||
|  |     rn   = zeros(8,1); | ||||||
|  |  | ||||||
|  |     for i = 1:8 | ||||||
|  |         rn(i) = rtop^(i+1); | ||||||
|  |     end | ||||||
|  |      | ||||||
|  |     alpha = [2*a, 2*a^2+4*b/3, a*(a^2+3*b),... | ||||||
|  |         a^4/5+2.4*a^2*b+1.2*b^2, 2*a*b*(a^2+3*b)/3,... | ||||||
|  |         b^2*(6*a^2+4*b)*1.428571e-1, 0, 0]; | ||||||
|  |      | ||||||
|  |     if b^2 > 1.0e-35 | ||||||
|  |         alpha(7) = a*b^3/2;  | ||||||
|  |         alpha(8) = b^4/9;  | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     dr = rtop; | ||||||
|  |     dr = dr + alpha*rn; | ||||||
|  |     tropo = tropo + dr*ref*1000; | ||||||
|  |      | ||||||
|  |     if done == 'TRUE ' | ||||||
|  |         ddr = tropo;  | ||||||
|  |         break;  | ||||||
|  |     end | ||||||
|  |      | ||||||
|  |     done    = 'TRUE '; | ||||||
|  |     refsea  = (371900.0e-6/tksea-12.92e-6)/tksea; | ||||||
|  |     htop    = 1.1385e-5 * (1255/tksea+0.05)/refsea; | ||||||
|  |     ref     = refsea * e0sea * ((htop-hsta)/htop)^4; | ||||||
|  | end; | ||||||
|  | %%%%%%%%% end tropo.m  %%%%%%%%%%%%%%%%%%% | ||||||
							
								
								
									
										177
									
								
								src/utils/matlab/libs/gps_l1_ca_dll_fll_pll_read_tracking_dump.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								src/utils/matlab/libs/gps_l1_ca_dll_fll_pll_read_tracking_dump.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,177 @@ | |||||||
|  | % /*! | ||||||
|  | %  * \file gps_l1_ca_dll_fll_pll_read_tracking_dump.m | ||||||
|  | %  * \brief Read GNSS-SDR Tracking dump binary file into MATLAB. | ||||||
|  | %  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  * | ||||||
|  | %  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is a software defined Global Navigation | ||||||
|  | %  *          Satellite Systems receiver | ||||||
|  | %  * | ||||||
|  | %  * This file is part of GNSS-SDR. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  | %  * it under the terms of the GNU General Public License as published by | ||||||
|  | %  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  | %  * at your option) any later version. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  | %  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | %  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | %  * GNU General Public License for more details. | ||||||
|  | %  * | ||||||
|  | %  * You should have received a copy of the GNU General Public License | ||||||
|  | %  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | %  * | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  */              | ||||||
|  | function [GNSS_tracking] = gps_l1_ca_dll_fll_pll_read_tracking_dump (filename, count) | ||||||
|  |  | ||||||
|  |   %% usage: gps_l1_ca_dll_fll_pll_read_tracking_dump (filename, [count]) | ||||||
|  |   %% | ||||||
|  |   %% open GNSS-SDR tracking binary log file .dat and return the contents | ||||||
|  |   %% | ||||||
|  |  | ||||||
|  |   m = nargchk (1,2,nargin); | ||||||
|  |   num_float_vars=16; | ||||||
|  |   num_double_vars=1; | ||||||
|  |   double_size_bytes=8; | ||||||
|  |   float_size_bytes=4; | ||||||
|  |   skip_bytes_each_read=float_size_bytes*num_float_vars+double_size_bytes*num_double_vars; | ||||||
|  |   bytes_shift=0; | ||||||
|  |   if (m) | ||||||
|  |     usage (m); | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   if (nargin < 2) | ||||||
|  |     count = Inf; | ||||||
|  |   end | ||||||
|  |     %loops_counter = fread (f, count, 'uint32',4*12); | ||||||
|  |   f = fopen (filename, 'rb'); | ||||||
|  |   if (f < 0) | ||||||
|  |   else | ||||||
|  |     v1 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v2 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v3 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v4 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v5 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v6 = fread (f, count, 'uint32',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v7 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v8 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v9 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v10 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v11 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v12 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v13 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v14 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v15 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |             bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v16 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |             bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v17 = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); | ||||||
|  |     fclose (f); | ||||||
|  |      | ||||||
|  |     %%%%%%%% output vars %%%%%%%% | ||||||
|  |  | ||||||
|  | % 			// EPR | ||||||
|  | % 			d_dump_file.write((char*)&tmp_E, sizeof(float)); | ||||||
|  | % 			d_dump_file.write((char*)&tmp_P, sizeof(float)); | ||||||
|  | % 			d_dump_file.write((char*)&tmp_L, sizeof(float)); | ||||||
|  | % 			// PROMPT I and Q (to analyze navigation symbols) | ||||||
|  | % 			d_dump_file.write((char*)&prompt_I, sizeof(float)); | ||||||
|  | % 			d_dump_file.write((char*)&prompt_Q, sizeof(float)); | ||||||
|  | % 			// PRN start sample stamp | ||||||
|  | % 			//tmp_float=(float)d_sample_counter; | ||||||
|  | % 			d_dump_file.write((char*)&d_sample_counter, sizeof(unsigned long int)); | ||||||
|  | % 			// accumulated carrier phase | ||||||
|  | % 			d_dump_file.write((char*)&d_acc_carrier_phase_rad, sizeof(float)); | ||||||
|  | %  | ||||||
|  | % 			// carrier and code frequency | ||||||
|  | % 			d_dump_file.write((char*)&d_carrier_doppler_hz, sizeof(float)); | ||||||
|  | % 			d_dump_file.write((char*)&d_code_freq_hz, sizeof(float)); | ||||||
|  | %  | ||||||
|  | % 			//PLL commands | ||||||
|  | % 			d_dump_file.write((char*)&PLL_discriminator_hz, sizeof(float)); | ||||||
|  | % 			d_dump_file.write((char*)&carr_nco_hz, sizeof(float)); | ||||||
|  | %  | ||||||
|  | % 			//DLL commands | ||||||
|  | % 			d_dump_file.write((char*)&code_error_chips, sizeof(float)); | ||||||
|  | % 			d_dump_file.write((char*)&d_code_phase_samples, sizeof(float)); | ||||||
|  | %  | ||||||
|  | % 			// CN0 and carrier lock test | ||||||
|  | % 			d_dump_file.write((char*)&d_CN0_SNV_dB_Hz, sizeof(float)); | ||||||
|  | % 			d_dump_file.write((char*)&d_carrier_lock_test, sizeof(float)); | ||||||
|  | %  | ||||||
|  | % 			// AUX vars (for debug purposes) | ||||||
|  | % 			tmp_float=0; | ||||||
|  | % 			d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||||
|  | % 			d_dump_file.write((char*)&d_sample_counter_seconds, sizeof(double)); | ||||||
|  |              | ||||||
|  |     E=v1; | ||||||
|  |     P=v2; | ||||||
|  |     L=v3; | ||||||
|  |     prompt_I=v4; | ||||||
|  |     prompt_Q=v5; | ||||||
|  |     PRN_start_sample=v6; | ||||||
|  |     acc_carrier_phase_rad=v7; | ||||||
|  |     carrier_doppler_hz=v8; | ||||||
|  |     code_freq_hz=v9; | ||||||
|  |     PLL_discriminator_hz=v10; | ||||||
|  |     carr_nco_hz=v11; | ||||||
|  |     code_error_chips=v12; | ||||||
|  |     code_phase_samples=v13; | ||||||
|  |     CN0_SNV_dB_Hz=v14; | ||||||
|  |     carrier_lock_test=v15; | ||||||
|  |     var1=v16; | ||||||
|  |     var2=v17; | ||||||
|  |      | ||||||
|  |     GNSS_tracking.E=E; | ||||||
|  |     GNSS_tracking.P=P; | ||||||
|  |     GNSS_tracking.L=L; | ||||||
|  |     GNSS_tracking.prompt_I=prompt_I; | ||||||
|  |     GNSS_tracking.prompt_Q=prompt_Q; | ||||||
|  |     GNSS_tracking.PRN_start_sample=PRN_start_sample; | ||||||
|  |     GNSS_tracking.acc_carrier_phase_rad=acc_carrier_phase_rad; | ||||||
|  |     GNSS_tracking.carrier_doppler_hz=carrier_doppler_hz; | ||||||
|  |     GNSS_tracking.code_freq_hz=code_freq_hz; | ||||||
|  |     GNSS_tracking.PLL_discriminator_hz=PLL_discriminator_hz; | ||||||
|  |     GNSS_tracking.carr_nco=carr_nco_hz; | ||||||
|  |     GNSS_tracking.code_error_chips=code_error_chips; | ||||||
|  |     GNSS_tracking.code_phase_samples=code_phase_samples; | ||||||
|  |     GNSS_tracking.CN0_SNV_dB_Hz=CN0_SNV_dB_Hz; | ||||||
|  |     GNSS_tracking.carrier_lock_test=carrier_lock_test; | ||||||
|  |     GNSS_tracking.var1=var1; | ||||||
|  |     GNSS_tracking.var2=var2; | ||||||
|  |   end | ||||||
|  |    | ||||||
| @@ -0,0 +1,45 @@ | |||||||
|  | % Javier Arribas 2011              | ||||||
|  | function [preamble_delay_ms,prn_delay_ms] = gps_l1_ca_dll_pll_read_observables_dump (channels, filename, count) | ||||||
|  |  | ||||||
|  |   %% usage: read_tracking_dat (filename, [count]) | ||||||
|  |   %% | ||||||
|  |   %% open GNSS-SDR tracking binary log file .dat and return the contents | ||||||
|  |   %% | ||||||
|  |  | ||||||
|  |   m = nargchk (1,2,nargin); | ||||||
|  |   num_double_vars=2; | ||||||
|  |   double_size_bytes=8; | ||||||
|  |   skip_bytes_each_read=double_size_bytes*num_double_vars*channels; | ||||||
|  |   bytes_shift=0; | ||||||
|  |   if (m) | ||||||
|  |     usage (m); | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   if (nargin < 3) | ||||||
|  |     count = Inf; | ||||||
|  |   end | ||||||
|  |     %loops_counter = fread (f, count, 'uint32',4*12); | ||||||
|  |   f = fopen (filename, 'rb'); | ||||||
|  |   if (f < 0) | ||||||
|  |   else | ||||||
|  |     for N=1:1:channels | ||||||
|  |         preamble_delay_ms(N,:) = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+double_size_bytes; | ||||||
|  |         fseek(f,bytes_shift,'bof'); % move to next interleaved | ||||||
|  |         prn_delay_ms(N,:) = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+double_size_bytes; | ||||||
|  |         fseek(f,bytes_shift,'bof'); % move to next interleaved | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     fclose (f); | ||||||
|  |      | ||||||
|  |     %%%%%%%% output vars %%%%%%%% | ||||||
|  | %     	  for (unsigned int i=0; i<d_nchannels ; i++) | ||||||
|  | %     	    { | ||||||
|  | %     		  tmp_double=in[i][0].preamble_delay_ms; | ||||||
|  | %     		  d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | %     		  tmp_double=in[i][0].prn_delay_ms; | ||||||
|  | %     		  d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | %     	    } | ||||||
|  |   end | ||||||
|  |    | ||||||
							
								
								
									
										177
									
								
								src/utils/matlab/libs/gps_l1_ca_dll_pll_read_tracking_dump.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								src/utils/matlab/libs/gps_l1_ca_dll_pll_read_tracking_dump.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,177 @@ | |||||||
|  | % /*! | ||||||
|  | %  * \file gps_l1_ca_dll_pll_read_tracking_dump.m | ||||||
|  | %  * \brief Read GNSS-SDR Tracking dump binary file into MATLAB. | ||||||
|  | %  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  * | ||||||
|  | %  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is a software defined Global Navigation | ||||||
|  | %  *          Satellite Systems receiver | ||||||
|  | %  * | ||||||
|  | %  * This file is part of GNSS-SDR. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  | %  * it under the terms of the GNU General Public License as published by | ||||||
|  | %  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  | %  * at your option) any later version. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  | %  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | %  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | %  * GNU General Public License for more details. | ||||||
|  | %  * | ||||||
|  | %  * You should have received a copy of the GNU General Public License | ||||||
|  | %  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | %  * | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  */              | ||||||
|  | function [GNSS_tracking] = gps_l1_ca_dll_pll_read_tracking_dump (filename, count) | ||||||
|  |  | ||||||
|  |   %% usage: gps_l1_ca_dll_pll_read_tracking_dump (filename, [count]) | ||||||
|  |   %% | ||||||
|  |   %% open GNSS-SDR tracking binary log file .dat and return the contents | ||||||
|  |   %% | ||||||
|  |  | ||||||
|  |   m = nargchk (1,2,nargin); | ||||||
|  |   num_float_vars=16; | ||||||
|  |   num_double_vars=1; | ||||||
|  |   double_size_bytes=8; | ||||||
|  |   float_size_bytes=4; | ||||||
|  |   skip_bytes_each_read=float_size_bytes*num_float_vars+double_size_bytes*num_double_vars; | ||||||
|  |   bytes_shift=0; | ||||||
|  |   if (m) | ||||||
|  |     usage (m); | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   if (nargin < 2) | ||||||
|  |     count = Inf; | ||||||
|  |   end | ||||||
|  |     %loops_counter = fread (f, count, 'uint32',4*12); | ||||||
|  |   f = fopen (filename, 'rb'); | ||||||
|  |   if (f < 0) | ||||||
|  |   else | ||||||
|  |     v1 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v2 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v3 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v4 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v5 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v6 = fread (f, count, 'uint32',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v7 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v8 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v9 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v10 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v11 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v12 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v13 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v14 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v15 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |             bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v16 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); | ||||||
|  |             bytes_shift=bytes_shift+float_size_bytes; | ||||||
|  |     fseek(f,bytes_shift,'bof'); % move to next interleaved float | ||||||
|  |     v17 = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); | ||||||
|  |     fclose (f); | ||||||
|  |      | ||||||
|  |     %%%%%%%% output vars %%%%%%%% | ||||||
|  |      | ||||||
|  | % 				// EPR | ||||||
|  | % 				d_dump_file.write((char*)&tmp_E, sizeof(float)); | ||||||
|  | % 				d_dump_file.write((char*)&tmp_P, sizeof(float)); | ||||||
|  | % 				d_dump_file.write((char*)&tmp_L, sizeof(float)); | ||||||
|  | % 				// PROMPT I and Q (to analyze navigation symbols) | ||||||
|  | % 				d_dump_file.write((char*)&prompt_I, sizeof(float)); | ||||||
|  | % 				d_dump_file.write((char*)&prompt_Q, sizeof(float)); | ||||||
|  | % 				// PRN start sample stamp | ||||||
|  | % 				//tmp_float=(float)d_sample_counter; | ||||||
|  | % 				d_dump_file.write((char*)&d_sample_counter, sizeof(unsigned long int)); | ||||||
|  | % 				// accumulated carrier phase | ||||||
|  | % 				d_dump_file.write((char*)&d_acc_carrier_phase_rad, sizeof(float)); | ||||||
|  | %  | ||||||
|  | % 				// carrier and code frequency | ||||||
|  | % 				d_dump_file.write((char*)&d_carrier_doppler_hz, sizeof(float)); | ||||||
|  | % 				d_dump_file.write((char*)&d_code_freq_hz, sizeof(float)); | ||||||
|  | %  | ||||||
|  | % 				//PLL commands | ||||||
|  | % 				d_dump_file.write((char*)&carr_error, sizeof(float)); | ||||||
|  | % 				d_dump_file.write((char*)&carr_nco, sizeof(float)); | ||||||
|  | %  | ||||||
|  | % 				//DLL commands | ||||||
|  | % 				d_dump_file.write((char*)&code_error, sizeof(float)); | ||||||
|  | % 				d_dump_file.write((char*)&code_nco, sizeof(float)); | ||||||
|  | %  | ||||||
|  | % 				// CN0 and carrier lock test | ||||||
|  | % 				d_dump_file.write((char*)&d_CN0_SNV_dB_Hz, sizeof(float)); | ||||||
|  | % 				d_dump_file.write((char*)&d_carrier_lock_test, sizeof(float)); | ||||||
|  | %  | ||||||
|  | % 				// AUX vars (for debug purposes) | ||||||
|  | % 				tmp_float=0; | ||||||
|  | % 				d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||||
|  | % 				d_dump_file.write((char*)&d_sample_counter_seconds, sizeof(double)); | ||||||
|  |                  | ||||||
|  |     E=v1; | ||||||
|  |     P=v2; | ||||||
|  |     L=v3; | ||||||
|  |     prompt_I=v4; | ||||||
|  |     prompt_Q=v5; | ||||||
|  |     PRN_start_sample=v6; | ||||||
|  |     acc_carrier_phase_rad=v7; | ||||||
|  |     carrier_doppler_hz=v8; | ||||||
|  |     code_freq_hz=v9; | ||||||
|  |     carr_error=v10; | ||||||
|  |     carr_nco=v11; | ||||||
|  |     code_error=v12; | ||||||
|  |     code_nco=v13; | ||||||
|  |     CN0_SNV_dB_Hz=v14; | ||||||
|  |     carrier_lock_test=v15; | ||||||
|  |     var1=v16; | ||||||
|  |     var2=v17; | ||||||
|  |      | ||||||
|  |     GNSS_tracking.E=E; | ||||||
|  |     GNSS_tracking.P=P; | ||||||
|  |     GNSS_tracking.L=L; | ||||||
|  |     GNSS_tracking.prompt_I=prompt_I; | ||||||
|  |     GNSS_tracking.prompt_Q=prompt_Q; | ||||||
|  |     GNSS_tracking.PRN_start_sample=PRN_start_sample; | ||||||
|  |     GNSS_tracking.acc_carrier_phase_rad=acc_carrier_phase_rad; | ||||||
|  |     GNSS_tracking.carrier_doppler_hz=carrier_doppler_hz; | ||||||
|  |     GNSS_tracking.code_freq_hz=code_freq_hz; | ||||||
|  |     GNSS_tracking.carr_error=carr_error; | ||||||
|  |     GNSS_tracking.carr_nco=carr_nco; | ||||||
|  |     GNSS_tracking.code_error=code_error; | ||||||
|  |     GNSS_tracking.code_nco=code_nco; | ||||||
|  |     GNSS_tracking.CN0_SNV_dB_Hz=CN0_SNV_dB_Hz; | ||||||
|  |     GNSS_tracking.carrier_lock_test=carrier_lock_test; | ||||||
|  |     GNSS_tracking.var1=var1; | ||||||
|  |     GNSS_tracking.var2=var2; | ||||||
|  |   end | ||||||
|  |    | ||||||
							
								
								
									
										114
									
								
								src/utils/matlab/libs/gps_l1_ca_pvt_read_pvt_dump.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/utils/matlab/libs/gps_l1_ca_pvt_read_pvt_dump.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | |||||||
|  | % /*! | ||||||
|  | %  * \file gps_l1_ca_pvt_read_pvt_dump.m | ||||||
|  | %  * \brief Read GNSS-SDR PVT lib dump binary file into MATLAB. The resulting | ||||||
|  | %  structure is compatible with the K.Borre MATLAB-based receiver. | ||||||
|  | %  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  * | ||||||
|  | %  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is a software defined Global Navigation | ||||||
|  | %  *          Satellite Systems receiver | ||||||
|  | %  * | ||||||
|  | %  * This file is part of GNSS-SDR. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  | %  * it under the terms of the GNU General Public License as published by | ||||||
|  | %  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  | %  * at your option) any later version. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  | %  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | %  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | %  * GNU General Public License for more details. | ||||||
|  | %  * | ||||||
|  | %  * You should have received a copy of the GNU General Public License | ||||||
|  | %  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | %  * | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  */         | ||||||
|  | function [navSolutions] = gps_l1_ca_pvt_read_pvt_dump (filename, count) | ||||||
|  |  | ||||||
|  |   %% usage: gps_l1_ca_pvt_read_pvt_dump (filename, [count]) | ||||||
|  |   %% | ||||||
|  |   %% open GNSS-SDR PVT binary log file .dat and return the contents | ||||||
|  |   %% | ||||||
|  | %  | ||||||
|  | % //  PVT GPS time | ||||||
|  | % tmp_double=GPS_current_time; | ||||||
|  | % d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | % // ECEF User Position East [m] | ||||||
|  | % tmp_double=mypos(0); | ||||||
|  | % d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | % // ECEF User Position North [m] | ||||||
|  | % tmp_double=mypos(1); | ||||||
|  | % d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | % // ECEF User Position Up [m] | ||||||
|  | % tmp_double=mypos(2); | ||||||
|  | % d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | % // User clock offset [s] | ||||||
|  | % tmp_double=mypos(3); | ||||||
|  | % d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | % // GEO user position Latitude [deg] | ||||||
|  | % tmp_double=d_latitude_d; | ||||||
|  | % d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | % // GEO user position Longitude [deg] | ||||||
|  | % tmp_double=d_longitude_d; | ||||||
|  | % d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | % // GEO user position Height [m] | ||||||
|  | % tmp_double=d_height_m; | ||||||
|  | % d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  |                  | ||||||
|  |   m = nargchk (1,2,nargin); | ||||||
|  |   num_double_vars=8; | ||||||
|  |   double_size_bytes=8; | ||||||
|  |   skip_bytes_each_read=double_size_bytes*num_double_vars; | ||||||
|  |   bytes_shift=0; | ||||||
|  |   if (m) | ||||||
|  |     usage (m); | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   if (nargin < 3) | ||||||
|  |     count = Inf; | ||||||
|  |   end | ||||||
|  |     %loops_counter = fread (f, count, 'uint32',4*12); | ||||||
|  |   f = fopen (filename, 'rb'); | ||||||
|  |   if (f < 0) | ||||||
|  |   else | ||||||
|  |         GPS_current_time = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+double_size_bytes; | ||||||
|  |         fseek(f,bytes_shift,'bof'); % move to next interleaved | ||||||
|  |         ECEF_X = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+double_size_bytes; | ||||||
|  |         fseek(f,bytes_shift,'bof'); % move to next interleaved | ||||||
|  |         ECEF_Y = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+double_size_bytes; | ||||||
|  |         fseek(f,bytes_shift,'bof'); % move to next interleaved | ||||||
|  |         ECEF_Z = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+double_size_bytes; | ||||||
|  |         fseek(f,bytes_shift,'bof'); % move to next interleaved | ||||||
|  |         Clock_Offset = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+double_size_bytes; | ||||||
|  |         fseek(f,bytes_shift,'bof'); % move to next interleaved | ||||||
|  |         Lat = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+double_size_bytes; | ||||||
|  |         fseek(f,bytes_shift,'bof'); % move to next interleaved | ||||||
|  |         Long = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+double_size_bytes; | ||||||
|  |         fseek(f,bytes_shift,'bof'); % move to next interleaved | ||||||
|  |         Height = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); | ||||||
|  |         bytes_shift=bytes_shift+double_size_bytes; | ||||||
|  |         fseek(f,bytes_shift,'bof'); % move to next interleaved | ||||||
|  |         fclose (f); | ||||||
|  |   end | ||||||
|  |    | ||||||
|  |   navSolutions.X=ECEF_X.'; | ||||||
|  |   navSolutions.Y=ECEF_Y.'; | ||||||
|  |   navSolutions.Z=ECEF_Z.'; | ||||||
|  |   navSolutions.dt=Clock_Offset.'; | ||||||
|  |   navSolutions.latitude=Lat.'; | ||||||
|  |   navSolutions.longitude=Long.'; | ||||||
|  |   navSolutions.height=Height.'; | ||||||
|  |   navSolutions.TransmitTime=GPS_current_time.'; | ||||||
|  |    | ||||||
|  |    | ||||||
							
								
								
									
										170
									
								
								src/utils/matlab/libs/plotNavigation.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								src/utils/matlab/libs/plotNavigation.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,170 @@ | |||||||
|  | % /*! | ||||||
|  | %  * \file plotNavigation.m | ||||||
|  | %  * \brief  | ||||||
|  | %   Functions plots variations of coordinates over time and a 3D position | ||||||
|  | %   plot. It plots receiver coordinates in UTM system or coordinate offsets if | ||||||
|  | %   the true UTM receiver coordinates are provided.   | ||||||
|  | %  * \author Darius Plausinaitis | ||||||
|  | %  * Modified by Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  * | ||||||
|  | %  * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors) | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is a software defined Global Navigation | ||||||
|  | %  *          Satellite Systems receiver | ||||||
|  | %  * | ||||||
|  | %  * This file is part of GNSS-SDR. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  | %  * it under the terms of the GNU General Public License as published by | ||||||
|  | %  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  | %  * at your option) any later version. | ||||||
|  | %  * | ||||||
|  | %  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  | %  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | %  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | %  * GNU General Public License for more details. | ||||||
|  | %  * | ||||||
|  | %  * You should have received a copy of the GNU General Public License | ||||||
|  | %  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | %  * | ||||||
|  | %  * ------------------------------------------------------------------------- | ||||||
|  | %  */  | ||||||
|  |  | ||||||
|  | function plotNavigation(navSolutions, settings,plot_skyplot) | ||||||
|  | %Functions plots variations of coordinates over time and a 3D position | ||||||
|  | %plot. It plots receiver coordinates in UTM system or coordinate offsets if | ||||||
|  | %the true UTM receiver coordinates are provided.   | ||||||
|  | % | ||||||
|  | %plotNavigation(navSolutions, settings) | ||||||
|  | % | ||||||
|  | %   Inputs: | ||||||
|  | %       navSolutions    - Results from navigation solution function. It | ||||||
|  | %                       contains measured pseudoranges and receiver | ||||||
|  | %                       coordinates. | ||||||
|  | %       settings        - Receiver settings. The true receiver coordinates | ||||||
|  | %                       are contained in this structure. | ||||||
|  | %       plot_skyplot    - If ==1 then use satellite coordinates to plot the | ||||||
|  | %                       the satellite positions | ||||||
|  |  | ||||||
|  | %% Plot results in the necessary data exists ============================== | ||||||
|  | if (~isempty(navSolutions)) | ||||||
|  |  | ||||||
|  |     %% If reference position is not provided, then set reference position | ||||||
|  |     %% to the average postion | ||||||
|  |     if isnan(settings.truePosition.E) || isnan(settings.truePosition.N) ... | ||||||
|  |                                       || isnan(settings.truePosition.U) | ||||||
|  |  | ||||||
|  |         %=== Compute mean values ==========================================  | ||||||
|  |         % Remove NaN-s or the output of the function MEAN will be NaN. | ||||||
|  |         refCoord.E = mean(navSolutions.E(~isnan(navSolutions.E))); | ||||||
|  |         refCoord.N = mean(navSolutions.N(~isnan(navSolutions.N))); | ||||||
|  |         refCoord.U = mean(navSolutions.U(~isnan(navSolutions.U))); | ||||||
|  |  | ||||||
|  |         %Also convert geodetic coordinates to deg:min:sec vector format | ||||||
|  |         meanLongitude = dms2mat(deg2dms(... | ||||||
|  |             mean(navSolutions.longitude(~isnan(navSolutions.longitude)))), -5); | ||||||
|  |         meanLatitude  = dms2mat(deg2dms(... | ||||||
|  |             mean(navSolutions.latitude(~isnan(navSolutions.latitude)))), -5); | ||||||
|  |  | ||||||
|  |         LatLong_str=[num2str(meanLatitude(1)), 'º', ... | ||||||
|  |                             num2str(meanLatitude(2)), '''', ... | ||||||
|  |                             num2str(meanLatitude(3)), '''''', ... | ||||||
|  |                             ',', ... | ||||||
|  |                             num2str(meanLongitude(1)), 'º', ... | ||||||
|  |                             num2str(meanLongitude(2)), '''', ... | ||||||
|  |                             num2str(meanLongitude(3)), ''''''] | ||||||
|  |                              | ||||||
|  |                              | ||||||
|  |          | ||||||
|  |         refPointLgText = ['Mean Position\newline  Lat: ', ... | ||||||
|  |                             num2str(meanLatitude(1)), '{\circ}', ... | ||||||
|  |                             num2str(meanLatitude(2)), '{\prime}', ... | ||||||
|  |                             num2str(meanLatitude(3)), '{\prime}{\prime}', ... | ||||||
|  |                          '\newline Lng: ', ... | ||||||
|  |                             num2str(meanLongitude(1)), '{\circ}', ... | ||||||
|  |                             num2str(meanLongitude(2)), '{\prime}', ... | ||||||
|  |                             num2str(meanLongitude(3)), '{\prime}{\prime}', ... | ||||||
|  |                          '\newline Hgt: ', ... | ||||||
|  |                             num2str(mean(navSolutions.height(~isnan(navSolutions.height))), '%+6.1f')]; | ||||||
|  |                    | ||||||
|  |     else | ||||||
|  |         % compute the mean error for static receiver | ||||||
|  |         mean_position.E = mean(navSolutions.E(~isnan(navSolutions.E))); | ||||||
|  |         mean_position.N = mean(navSolutions.N(~isnan(navSolutions.N))); | ||||||
|  |         mean_position.U = mean(navSolutions.U(~isnan(navSolutions.U))); | ||||||
|  |         refCoord.E = settings.truePosition.E; | ||||||
|  |         refCoord.N = settings.truePosition.N; | ||||||
|  |         refCoord.U = settings.truePosition.U; | ||||||
|  |          | ||||||
|  |         error_meters=sqrt((mean_position.E-refCoord.E)^2+(mean_position.N-refCoord.N)^2+(mean_position.U-refCoord.U)^2); | ||||||
|  |          | ||||||
|  |         refPointLgText = ['Reference Position, Mean 3D error = ' num2str(error_meters) ' [m]']; | ||||||
|  |     end     | ||||||
|  |       | ||||||
|  |     figureNumber = 300; | ||||||
|  |     % The 300 is chosen for more convenient handling of the open | ||||||
|  |     % figure windows, when many figures are closed and reopened. Figures | ||||||
|  |     % drawn or opened by the user, will not be "overwritten" by this | ||||||
|  |     % function if the auto numbering is not used. | ||||||
|  |   | ||||||
|  |     %=== Select (or create) and clear the figure ========================== | ||||||
|  |     figure(figureNumber); | ||||||
|  |     clf   (figureNumber); | ||||||
|  |     set   (figureNumber, 'Name', 'Navigation solutions'); | ||||||
|  |   | ||||||
|  |     %--- Draw axes -------------------------------------------------------- | ||||||
|  |     handles(1, 1) = subplot(4, 2, 1 : 4); | ||||||
|  |     handles(3, 1) = subplot(4, 2, [5, 7]); | ||||||
|  |     handles(3, 2) = subplot(4, 2, [6, 8]);     | ||||||
|  |   | ||||||
|  | %% Plot all figures ======================================================= | ||||||
|  |   | ||||||
|  |     %--- Coordinate differences in UTM system ----------------------------- | ||||||
|  |     plot(handles(1, 1), [(navSolutions.E - refCoord.E)', ... | ||||||
|  |                          (navSolutions.N - refCoord.N)',... | ||||||
|  |                          (navSolutions.U - refCoord.U)']); | ||||||
|  |   | ||||||
|  |     title (handles(1, 1), 'Coordinates variations in UTM system'); | ||||||
|  |     legend(handles(1, 1), 'E', 'N', 'U'); | ||||||
|  |     xlabel(handles(1, 1), ['Measurement period: ', ... | ||||||
|  |                                     num2str(settings.navSolPeriod), 'ms']); | ||||||
|  |     ylabel(handles(1, 1), 'Variations (m)'); | ||||||
|  |     grid  (handles(1, 1)); | ||||||
|  |     axis  (handles(1, 1), 'tight');     | ||||||
|  |   | ||||||
|  |     %--- Position plot in UTM system -------------------------------------- | ||||||
|  |     plot3 (handles(3, 1), navSolutions.E - refCoord.E, ... | ||||||
|  |                           navSolutions.N - refCoord.N, ...  | ||||||
|  |                           navSolutions.U - refCoord.U, '+'); | ||||||
|  |     hold  (handles(3, 1), 'on'); | ||||||
|  |                        | ||||||
|  |     %Plot the reference point | ||||||
|  |     plot3 (handles(3, 1), 0, 0, 0, 'r+', 'LineWidth', 1.5, 'MarkerSize', 10); | ||||||
|  |     hold  (handles(3, 1), 'off'); | ||||||
|  |      | ||||||
|  |     view  (handles(3, 1), 0, 90); | ||||||
|  |     axis  (handles(3, 1), 'equal'); | ||||||
|  |     grid  (handles(3, 1), 'minor');     | ||||||
|  |      | ||||||
|  |     legend(handles(3, 1), 'Measurements', refPointLgText); | ||||||
|  |   | ||||||
|  |     title (handles(3, 1), 'Positions in UTM system (3D plot)'); | ||||||
|  |     xlabel(handles(3, 1), 'East (m)'); | ||||||
|  |     ylabel(handles(3, 1), 'North (m)'); | ||||||
|  |     zlabel(handles(3, 1), 'Upping (m)'); | ||||||
|  |      | ||||||
|  |     if (plot_skyplot==1) | ||||||
|  |         %--- Satellite sky plot ----------------------------------------------- | ||||||
|  |         skyPlot(handles(3, 2), ... | ||||||
|  |                 navSolutions.channel.az, ... | ||||||
|  |                 navSolutions.channel.el, ... | ||||||
|  |                 navSolutions.channel.PRN(:, 1)); | ||||||
|  |              | ||||||
|  |         title (handles(3, 2), ['Sky plot (mean PDOP: ', ... | ||||||
|  |                                    num2str(mean(navSolutions.DOP(2,:))), ')']);   | ||||||
|  |     end | ||||||
|  |                             | ||||||
|  | else | ||||||
|  |     disp('plotNavigation: No navigation data to plot.'); | ||||||
|  | end % if (~isempty(navSolutions)) | ||||||
							
								
								
									
										153
									
								
								src/utils/matlab/libs/plotTracking.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								src/utils/matlab/libs/plotTracking.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,153 @@ | |||||||
|  | function plotTracking(channelList, trackResults, settings) | ||||||
|  | %This function plots the tracking results for the given channel list. | ||||||
|  | % | ||||||
|  | %plotTracking(channelList, trackResults, settings) | ||||||
|  | % | ||||||
|  | %   Inputs: | ||||||
|  | %       channelList     - list of channels to be plotted. | ||||||
|  | %       trackResults    - tracking results from the tracking function. | ||||||
|  | %       settings        - receiver settings. | ||||||
|  |  | ||||||
|  | %-------------------------------------------------------------------------- | ||||||
|  | %                           SoftGNSS v3.0 | ||||||
|  | %  | ||||||
|  | % Copyright (C) Darius Plausinaitis | ||||||
|  | % Written by Darius Plausinaitis | ||||||
|  | %-------------------------------------------------------------------------- | ||||||
|  | %This program is free software; you can redistribute it and/or | ||||||
|  | %modify it under the terms of the GNU General Public License | ||||||
|  | %as published by the Free Software Foundation; either version 2 | ||||||
|  | %of the License, or (at your option) any later version. | ||||||
|  | % | ||||||
|  | %This program is distributed in the hope that it will be useful, | ||||||
|  | %but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | %MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | %GNU General Public License for more details. | ||||||
|  | % | ||||||
|  | %You should have received a copy of the GNU General Public License | ||||||
|  | %along with this program; if not, write to the Free Software | ||||||
|  | %Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, | ||||||
|  | %USA. | ||||||
|  | %-------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | %CVS record: | ||||||
|  | %$Id: plotTracking.m,v 1.5.2.23 2006/08/14 14:45:14 dpl Exp $ | ||||||
|  |  | ||||||
|  | % Protection - if the list contains incorrect channel numbers | ||||||
|  | channelList = intersect(channelList, 1:settings.numberOfChannels); | ||||||
|  |  | ||||||
|  | %=== For all listed channels ============================================== | ||||||
|  | for channelNr = channelList | ||||||
|  |  | ||||||
|  | %% Select (or create) and clear the figure ================================ | ||||||
|  |     % The number 200 is added just for more convenient handling of the open | ||||||
|  |     % figure windows, when many figures are closed and reopened. | ||||||
|  |     % Figures drawn or opened by the user, will not be "overwritten" by | ||||||
|  |     % this function. | ||||||
|  |  | ||||||
|  |     figure(channelNr +200); | ||||||
|  |     clf(channelNr +200); | ||||||
|  |     set(channelNr +200, 'Name', ['Channel ', num2str(channelNr), ... | ||||||
|  |                                  ' (PRN ', ... | ||||||
|  |                                  num2str(trackResults(channelNr).PRN), ... | ||||||
|  |                                  ') results']); | ||||||
|  |  | ||||||
|  | %% Draw axes ============================================================== | ||||||
|  |         % Row 1 | ||||||
|  |         handles(1, 1) = subplot(3, 3, 1); | ||||||
|  |         handles(1, 2) = subplot(3, 3, [2 3]); | ||||||
|  |         % Row 2 | ||||||
|  |         handles(2, 1) = subplot(3, 3, 4); | ||||||
|  |         handles(2, 2) = subplot(3, 3, [5 6]); | ||||||
|  |         % Row 3 | ||||||
|  |         handles(3, 1) = subplot(3, 3, 7); | ||||||
|  |         handles(3, 2) = subplot(3, 3, 8); | ||||||
|  |         handles(3, 3) = subplot(3, 3, 9); | ||||||
|  |  | ||||||
|  | %% Plot all figures ======================================================= | ||||||
|  |  | ||||||
|  |         timeAxisInSeconds = (1:settings.msToProcess)/1000; | ||||||
|  |  | ||||||
|  |         %----- Discrete-Time Scatter Plot --------------------------------- | ||||||
|  |         plot(handles(1, 1), trackResults(channelNr).I_P,... | ||||||
|  |                             trackResults(channelNr).Q_P, ... | ||||||
|  |                             '.'); | ||||||
|  |  | ||||||
|  |         grid  (handles(1, 1)); | ||||||
|  |         axis  (handles(1, 1), 'equal'); | ||||||
|  |         title (handles(1, 1), 'Discrete-Time Scatter Plot'); | ||||||
|  |         xlabel(handles(1, 1), 'I prompt'); | ||||||
|  |         ylabel(handles(1, 1), 'Q prompt'); | ||||||
|  |  | ||||||
|  |         %----- Nav bits --------------------------------------------------- | ||||||
|  |         plot  (handles(1, 2), timeAxisInSeconds, ... | ||||||
|  |                               trackResults(channelNr).I_P); | ||||||
|  |  | ||||||
|  |         grid  (handles(1, 2)); | ||||||
|  |         title (handles(1, 2), 'Bits of the navigation message'); | ||||||
|  |         xlabel(handles(1, 2), 'Time (s)'); | ||||||
|  |         axis  (handles(1, 2), 'tight'); | ||||||
|  |  | ||||||
|  |         %----- PLL discriminator unfiltered-------------------------------- | ||||||
|  |         plot  (handles(2, 1), timeAxisInSeconds, ... | ||||||
|  |                               trackResults(channelNr).pllDiscr, 'r');       | ||||||
|  |  | ||||||
|  |         grid  (handles(2, 1)); | ||||||
|  |         axis  (handles(2, 1), 'tight'); | ||||||
|  |         xlabel(handles(2, 1), 'Time (s)'); | ||||||
|  |         ylabel(handles(2, 1), 'Amplitude'); | ||||||
|  |         title (handles(2, 1), 'Raw PLL discriminator'); | ||||||
|  |  | ||||||
|  |         %----- Correlation ------------------------------------------------ | ||||||
|  |         plot(handles(2, 2), timeAxisInSeconds, ... | ||||||
|  |                             [sqrt(trackResults(channelNr).I_E.^2 + ... | ||||||
|  |                                   trackResults(channelNr).Q_E.^2)', ... | ||||||
|  |                              sqrt(trackResults(channelNr).I_P.^2 + ... | ||||||
|  |                                   trackResults(channelNr).Q_P.^2)', ... | ||||||
|  |                              sqrt(trackResults(channelNr).I_L.^2 + ... | ||||||
|  |                                   trackResults(channelNr).Q_L.^2)'], ... | ||||||
|  |                             '-*'); | ||||||
|  |  | ||||||
|  |         grid  (handles(2, 2)); | ||||||
|  |         title (handles(2, 2), 'Correlation results'); | ||||||
|  |         xlabel(handles(2, 2), 'Time (s)'); | ||||||
|  |         axis  (handles(2, 2), 'tight'); | ||||||
|  |          | ||||||
|  |         hLegend = legend(handles(2, 2), '$\sqrt{I_{E}^2 + Q_{E}^2}$', ... | ||||||
|  |                                         '$\sqrt{I_{P}^2 + Q_{P}^2}$', ... | ||||||
|  |                                         '$\sqrt{I_{L}^2 + Q_{L}^2}$'); | ||||||
|  |                            | ||||||
|  |         %set interpreter from tex to latex. This will draw \sqrt correctly | ||||||
|  |         set(hLegend, 'Interpreter', 'Latex'); | ||||||
|  |  | ||||||
|  |         %----- PLL discriminator filtered---------------------------------- | ||||||
|  |         plot  (handles(3, 1), timeAxisInSeconds, ... | ||||||
|  |                               trackResults(channelNr).pllDiscrFilt, 'b');       | ||||||
|  |  | ||||||
|  |         grid  (handles(3, 1)); | ||||||
|  |         axis  (handles(3, 1), 'tight'); | ||||||
|  |         xlabel(handles(3, 1), 'Time (s)'); | ||||||
|  |         ylabel(handles(3, 1), 'Amplitude'); | ||||||
|  |         title (handles(3, 1), 'Filtered PLL discriminator'); | ||||||
|  |  | ||||||
|  |         %----- DLL discriminator unfiltered-------------------------------- | ||||||
|  |         plot  (handles(3, 2), timeAxisInSeconds, ... | ||||||
|  |                               trackResults(channelNr).dllDiscr, 'r');       | ||||||
|  |  | ||||||
|  |         grid  (handles(3, 2)); | ||||||
|  |         axis  (handles(3, 2), 'tight'); | ||||||
|  |         xlabel(handles(3, 2), 'Time (s)'); | ||||||
|  |         ylabel(handles(3, 2), 'Amplitude'); | ||||||
|  |         title (handles(3, 2), 'Raw DLL discriminator'); | ||||||
|  |  | ||||||
|  |         %----- DLL discriminator filtered---------------------------------- | ||||||
|  |         plot  (handles(3, 3), timeAxisInSeconds, ... | ||||||
|  |                               trackResults(channelNr).dllDiscrFilt, 'b');       | ||||||
|  |  | ||||||
|  |         grid  (handles(3, 3)); | ||||||
|  |         axis  (handles(3, 3), 'tight'); | ||||||
|  |         xlabel(handles(3, 3), 'Time (s)'); | ||||||
|  |         ylabel(handles(3, 3), 'Amplitude'); | ||||||
|  |         title (handles(3, 3), 'Filtered DLL discriminator'); | ||||||
|  |  | ||||||
|  | end % for channelNr = channelList | ||||||
| @@ -1,7 +0,0 @@ | |||||||
| #!/usr/bin/octave |  | ||||||
| arg_list = argv (); |  | ||||||
| x=read_float_binary (arg_list{1}); |  | ||||||
| figure(1); |  | ||||||
| plot(x); |  | ||||||
| figure(2) |  | ||||||
| input "press any key to end..." |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| # Load number of used satellites |  | ||||||
| satellites = load("./data/satellites.dat") |  | ||||||
| samples = load("./data/samples.dat") |  | ||||||
| sampling_frequency = load("./data/sampling_frequency.dat") |  | ||||||
| signal_duration = 1/(sampling_frequency/samples) |  | ||||||
|  |  | ||||||
| # Plot carrier spectrum |  | ||||||
| for i = [0:satellites-1] |  | ||||||
| 	figure(i+1); |  | ||||||
| 	file_sufix = strcat("_", num2str(i), ".dat"); |  | ||||||
| 	carrier = read_float_binary(strcat("./data/carrier_signal", file_sufix)); |  | ||||||
| 	plot_spectrum(carrier, sampling_frequency, signal_duration, ";carrier spectrum;"); |  | ||||||
| endfor |  | ||||||
| figure(satellites+1); |  | ||||||
| input "press any key to end..." |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| # Load number of used satellites |  | ||||||
| satellites = load("./data/satellites.dat") |  | ||||||
|  |  | ||||||
| # Plot delayed and resampled prn codes |  | ||||||
| for i = [0:satellites-1] |  | ||||||
| 	figure(i+1); |  | ||||||
| 	file_sufix = strcat("_", num2str(i), ".dat"); |  | ||||||
| 	delay = read_float_binary(strcat("./data/delay_signal", file_sufix)); |  | ||||||
| 	delay = prn_code(1:999); |  | ||||||
| 	delay = [prn_code; -0.5; +0.5]; |  | ||||||
| 	plot(prn_code, "1*"); |  | ||||||
|  |  | ||||||
| endfor |  | ||||||
| figure(satellites+1); |  | ||||||
| input "press any key to end..." |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| # Load number of used satellites |  | ||||||
| satellites = load("./data/satellites.dat") |  | ||||||
| samples = load("./data/samples.dat") |  | ||||||
| sampling_frequency = load("./data/sampling_frequency.dat") |  | ||||||
| signal_duration = 1/(sampling_frequency/samples) |  | ||||||
|  |  | ||||||
| # Plot delayed and resampled prn codes spectrum |  | ||||||
| for i = [0:satellites-1] |  | ||||||
| 	figure(i+1); |  | ||||||
| 	file_sufix = strcat("_", num2str(i), ".dat"); |  | ||||||
| 	delay = read_float_binary(strcat("./data/delay_signal", file_sufix)); |  | ||||||
| 	plot_spectrum(delay, sampling_frequency, signal_duration, ";delayed and resampled prn code spectrum;"); |  | ||||||
| endfor |  | ||||||
| figure(satellites+1); |  | ||||||
| input "press any key to end..." |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| # Load number of used satellites |  | ||||||
| satellites = load("./data/satellites.dat") |  | ||||||
| samples = load("./data/samples.dat") |  | ||||||
| sampling_frequency = load("./data/sampling_frequency.dat") |  | ||||||
| signal_duration = 1/(sampling_frequency/samples) |  | ||||||
|  |  | ||||||
| # Plot gps signal spectrum |  | ||||||
| figure(1); |  | ||||||
| gps_signal = read_float_binary("./data/gps_signal.dat"); |  | ||||||
| plot_spectrum(prn_code, sampling_frequency, signal_duration, ";gps signal spectrum;"); |  | ||||||
| figure(2); |  | ||||||
| input "press any key to end..." |  | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| x=read_float_binary("./data/pfssa.dat"); |  | ||||||
| figure(1); |  | ||||||
| plot(x) |  | ||||||
| figure(2); |  | ||||||
| input("Press any key..."); |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| # Load number of used satellites |  | ||||||
| satellites = load("./data/satellites.dat") |  | ||||||
|  |  | ||||||
| # Plot prn codes |  | ||||||
| for i = [0:satellites-1] |  | ||||||
| 	figure(i+1); |  | ||||||
| 	file_sufix = strcat("_", num2str(i), ".dat"); |  | ||||||
| 	prn_code = read_float_binary(strcat("./data/prn_code_signal", file_sufix)); |  | ||||||
| 	prn_code = prn_code(1:99); |  | ||||||
| 	prn_code = [prn_code; -2; +2]; |  | ||||||
| 	plot(prn_code, "1*"); |  | ||||||
|  |  | ||||||
| endfor |  | ||||||
| figure(satellites+1); |  | ||||||
| input "press any key to end..." |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| # Load number of used satellites |  | ||||||
| satellites = load("./data/satellites.dat") |  | ||||||
|  |  | ||||||
| # Plot resampled prn codes |  | ||||||
| for i = [0:satellites-1] |  | ||||||
| 	figure(i+1); |  | ||||||
| 	file_sufix = strcat("_", num2str(i), ".dat"); |  | ||||||
| 	resampled_prn_code = read_float_binary(strcat("./data/resampled_prn_code_signal", file_sufix)); |  | ||||||
| 	resampled_prn_code = resampled_prn_code(1:599); |  | ||||||
| 	resampled_prn_code = [resampled_prn_code; -2; +2]; |  | ||||||
| 	plot(resampled_prn_code, "1*"); |  | ||||||
|  |  | ||||||
| endfor |  | ||||||
| figure(satellites+1); |  | ||||||
| input "press any key to end..." |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| # Load number of used satellites |  | ||||||
| satellites = load("./data/satellites.dat") |  | ||||||
| samples = load("./data/samples.dat") |  | ||||||
| sampling_frequency = load("./data/sampling_frequency.dat") |  | ||||||
| signal_duration = 1/(sampling_frequency/samples) |  | ||||||
|  |  | ||||||
| # Plot resampled prn codes spectrum |  | ||||||
| for i = [0:satellites-1] |  | ||||||
| 	figure(i+1); |  | ||||||
| 	file_sufix = strcat("_", num2str(i), ".dat"); |  | ||||||
| 	resampled_prn_code = read_float_binary(strcat("./data/resampled_prn_code_signal", file_sufix)); |  | ||||||
| 	plot_spectrum(resampled_prn_code, sampling_frequency, signal_duration, ";resampled prn code spectrum;"); |  | ||||||
| endfor |  | ||||||
| figure(satellites+1); |  | ||||||
| input "press any key to end..." |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| phase=load("./data/prn_code_phase.dat"); |  | ||||||
| samples_per_code=load("./data/prn_code_samples_per_code.dat"); |  | ||||||
| fs=load("./data/prn_code_fs.dat"); |  | ||||||
| signal=read_float_binary("./data/prn_code_signal.dat"); |  | ||||||
|  |  | ||||||
| phase |  | ||||||
| samples_per_code |  | ||||||
| fs |  | ||||||
|  |  | ||||||
| if( phase == -1 ) |  | ||||||
| 	for i = [0:1022] |  | ||||||
| 		i |  | ||||||
| 		prn_code=signal([(i*samples_per_code)+1:(i+1)*samples_per_code]); |  | ||||||
| 		spectrum_analysis (prn_code,fs,0.001); |  | ||||||
| 	endfor |  | ||||||
| else |  | ||||||
| 	spectrum_analysis(signal, fs,0.001); |  | ||||||
| endif |  | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 Javier Arribas
					Javier Arribas