1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-14 12:10:34 +00:00

Merge Next with FPGA. Adding software-defined emulation of the sample counter

This commit is contained in:
Javier Arribas 2018-04-06 17:03:20 +02:00
commit 8e59a42ae2
265 changed files with 21296 additions and 20425 deletions

View File

@ -37,8 +37,6 @@ BreakBeforeBinaryOperators: None
BreakBeforeBraces: GNU
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
@ -56,12 +54,9 @@ IncludeCategories:
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
@ -80,7 +75,6 @@ PointerAlignment: Left
ReflowComments: true
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false

View File

@ -41,9 +41,10 @@ endif(NOT CMAKE_PREFIX_PATH)
########################################################################
# Determine optional blocks/libraries to be built (default: not built)
# Enable them here or at the command line by doing 'cmake -DENABLE_XXX=ON ../'
# Enable them at the command line by doing 'cmake -DENABLE_XXX=ON ../'
########################################################################
# Support of optional RF front-ends
option(ENABLE_UHD "Enable the use of UHD (driver for all USRP devices)" ON)
option(ENABLE_OSMOSDR "Enable the use of OsmoSDR and other front-ends (RTL-based dongles, HackRF, bladeRF, etc.) as signal source (experimental)" OFF)
option(ENABLE_FLEXIBAND "Enable the use of the signal source adater for the Teleorbit Flexiband GNURadio driver" OFF)
option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal source (experimental)" OFF)
@ -317,7 +318,7 @@ set(GNSSSDR_GNURADIO_MIN_VERSION "3.7.3")
set(GNSSSDR_BOOST_MIN_VERSION "1.45")
set(GNSSSDR_PYTHON_MIN_VERSION "2.7")
set(GNSSSDR_MAKO_MIN_VERSION "0.4.2")
set(GNSSSDR_ARMADILLO_MIN_VERSION "4.200.0")
set(GNSSSDR_ARMADILLO_MIN_VERSION "5.300.0")
set(GNSSSDR_MATIO_MIN_VERSION "1.5.3")
@ -331,7 +332,7 @@ set(GNSSSDR_ARMADILLO_LOCAL_VERSION "unstable")
set(GNSSSDR_GTEST_LOCAL_VERSION "1.8.0")
set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master")
set(GNSSSDR_GPSTK_LOCAL_VERSION "2.10")
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.11")
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.12")
@ -450,13 +451,13 @@ if(ENABLE_UNIT_TESTING OR ENABLE_SYSTEM_TESTING)
endif(LIBGTEST_DEV_DIR)
find_path(GTEST_INCLUDE_DIRS NAMES gtest/gtest.h PATHS ${GTEST_DIR}/include)
else(GTEST_DIR)
find_path(LIBGTEST_DEV_DIR NAMES src/gtest-all.cc PATHS /usr/src/googletest/googletest /usr/src/gtest /opt/local/src/gtest-1.7.0 )
find_path(LIBGTEST_DEV_DIR NAMES src/gtest-all.cc PATHS /usr/src/googletest/googletest /usr/src/gtest /usr/include/gtest /opt/local/src/gtest-1.7.0 )
find_path(GTEST_INCLUDE_DIRS NAMES gtest/gtest.h PATHS /usr/include /opt/local/src/gtest-1.7.0/include)
if(LIBGTEST_DEV_DIR)
message (STATUS "Googletest package has been found.")
else(LIBGTEST_DEV_DIR)
message (STATUS " Googletest has not been found.")
message (STATUS " Googletest will be downloaded and built automatically ")
message (STATUS " Googletest v${GNSSSDR_GTEST_LOCAL_VERSION} will be downloaded and built automatically ")
message (STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'. ")
endif(LIBGTEST_DEV_DIR)
endif(GTEST_DIR)
@ -700,7 +701,7 @@ set(LOCAL_GFLAGS false)
find_package(GFlags)
if (NOT GFlags_FOUND)
message (STATUS " gflags library has not been found.")
message (STATUS " gflags will be downloaded and built automatically ")
message (STATUS " gflags v${GNSSSDR_GFLAGS_LOCAL_VERSION} will be downloaded and built automatically ")
message (STATUS " when doing 'make'. ")
if(CMAKE_VERSION VERSION_LESS 3.2)
@ -768,7 +769,7 @@ if (NOT GLOG_FOUND OR ${LOCAL_GFLAGS})
if(NOT GFlags_FOUND)
message(STATUS " or it is likely not linked to gflags.")
endif(NOT GFlags_FOUND)
message (STATUS " glog will be downloaded and built automatically ")
message (STATUS " glog v${GNSSSDR_GLOG_LOCAL_VERSION} will be downloaded and built automatically ")
message (STATUS " when doing 'make'. ")
if(NOT ${LOCAL_GFLAGS})
add_library(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} UNKNOWN IMPORTED)
@ -957,7 +958,7 @@ endif(ARMADILLO_FOUND)
if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO)
message(STATUS " Armadillo has not been found.")
message(STATUS " Armadillo will be downloaded and built automatically")
message(STATUS " Armadillo ${GNSSSDR_ARMADILLO_LOCAL_VERSION} will be downloaded and built automatically")
message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'. ")
set(armadillo_BRANCH ${GNSSSDR_ARMADILLO_LOCAL_VERSION})
set(armadillo_RELEASE ${armadillo_BRANCH})
@ -1100,7 +1101,7 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS
if(MATIO_FOUND)
message(STATUS " Matio installed version (${MATIO_VERSION_STRING}) is too old (>= ${GNSSSDR_MATIO_MIN_VERSION} is required).")
endif(MATIO_FOUND)
message(STATUS " Matio will be downloaded and built automatically")
message(STATUS " Matio v${GNSSSDR_MATIO_LOCAL_VERSION} will be downloaded and built automatically")
message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'. ")
find_package(ZLIB)
if(ZLIB_FOUND)
@ -1132,7 +1133,7 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
message(FATAL_ERROR "aclocal is required to build matio from source")
endif(EXISTS "/usr/bin/aclocal-1.15" OR EXISTS "/usr/bin/aclocal-1.14" OR EXISTS "/usr/bin/aclocal-1.13" OR EXISTS "/usr/bin/aclocal-1.11" OR EXISTS "/usr/bin/aclocal-1.10")
endif(OS_IS_LINUX)
endif(OS_IS_LINUX)
find_package(HDF5)
if(HDF5_FOUND)
list(GET HDF5_LIBRARIES 0 HDF5_FIRST_DIR)
@ -1196,18 +1197,18 @@ endif(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_V
################################################################################
# USRP Hardware Driver (UHD) - OPTIONAL
################################################################################
find_package(UHD)
if(NOT UHD_FOUND)
set(ENABLE_UHD OFF)
message(STATUS " The USRP Hardware Driver (UHD) signal source will not be built,")
message(STATUS " so all USRP-based front-ends will not be usable.")
message(STATUS " Please check http://files.ettus.com/manual/")
else(NOT UHD_FOUND)
set(GR_REQUIRED_COMPONENTS UHD)
find_package(Gnuradio)
set(ENABLE_UHD ON)
endif(NOT UHD_FOUND)
if(ENABLE_UHD)
find_package(UHD)
if(NOT UHD_FOUND)
set(ENABLE_UHD OFF)
message(STATUS " The USRP Hardware Driver (UHD) signal source will not be built,")
message(STATUS " so all USRP-based front-ends will not be usable.")
message(STATUS " Please check http://files.ettus.com/manual/")
else(NOT UHD_FOUND)
set(GR_REQUIRED_COMPONENTS UHD)
find_package(Gnuradio)
endif(NOT UHD_FOUND)
endif(ENABLE_UHD)
################################################################################

View File

@ -67,7 +67,7 @@ GitHub](https://github.com/join).
GitHub](https://github.com/gnss-sdr/gnss-sdr/fork). This will copy the
whole gnss-sdr repository to your personal account.
3. Then, go to your favourite working folder in your computer and
3. Then, go to your favorite working folder in your computer and
clone your forked repository by typing (replacing ```YOUR_USERNAME``` by
the actual username of your GitHub account):
@ -128,7 +128,7 @@ $ git pull --rebase upstream next
### How to submit a pull request
Before submitting you code, please be sure to [apply clang-format](http://gnss-sdr.org/coding-style/#use-tools-for-automated-code-formatting).
Before submitting your code, please be sure to [apply clang-format](http://gnss-sdr.org/coding-style/#use-tools-for-automated-code-formatting).
When the contribution is ready, you can [submit a pull
request](https://github.com/gnss-sdr/gnss-sdr/compare/). Head to your

View File

@ -13,6 +13,7 @@ In the L1 band (centered at 1575.42 MHz):
In the L2 band (centered at 1227.60 MHz):
- 🛰 GPS L2C :white_check_mark:
- 🛰 GLONASS L2 C/A :white_check_mark:
In the L5 band (centered at 1176.45 MHz):
- 🛰 GPS L5 :white_check_mark:
@ -52,7 +53,7 @@ Before building GNSS-SDR, you need to install all the required dependencies. The
### Alternative 1: Install dependencies using software packages
If you want to start building and running GNSS-SDR as quick and easy as possible, the best option is to install all the required dependencies as binary packages.
If you want to start building and running GNSS-SDR as quick and easy as possible, the best option is to install all the required dependencies as binary packages.
#### Debian / Ubuntu
@ -84,7 +85,7 @@ $ sudo yum install make automake gcc gcc-c++ kernel-devel cmake git boost-devel
boost-date-time boost-system boost-filesystem boost-thread boost-chrono \
boost-serialization log4cpp-devel gnuradio-devel gr-osmosdr-devel \
blas-devel lapack-devel matio-devel armadillo-devel gflags-devel \
glog-devel openssl-devel python-mako python-six
glog-devel openssl-devel python-mako python-six
~~~~~~
Once you have installed these packages, you can jump directly to [download the source code and build GNSS-SDR](#download-and-build-linux).
@ -303,7 +304,7 @@ $ cmake ../
$ make
~~~~~~
By default, CMake will build the Release version, meaning that the compiler will generate a fast, optimized executable. This is the recommended build type when using a RF front-end and you need to attain real time. If working with a file (and thus without real-time constraints), you may want to obtain more information about the internals of the receiver, as well as more fine-grained logging. This can be done by building the Debug version, by doing:
By default, CMake will build the Release version, meaning that the compiler will generate a fast, optimized executable. This is the recommended build type when using an RF front-end and you need to attain real time. If working with a file (and thus without real-time constraints), you may want to obtain more information about the internals of the receiver, as well as more fine-grained logging. This can be done by building the Debug version, by doing:
~~~~~~
$ cmake -DCMAKE_BUILD_TYPE=Debug ../
@ -696,8 +697,8 @@ Getting started
2. You will need a GPS active antenna, a [USRP](http://www.ettus.com/product) and a suitable USRP daughter board to receive GPS L1 C/A signals. GNSS-SDR require to have at least 2 MHz of bandwidth in 1.57542 GHz. (remember to enable the DC bias with the daughter board jumper).
We use a [DBSRX2](https://www.ettus.com/product/details/DBSRX2) to do the task, but you can try the newer Ettus' daughter boards as well.
3. The easiest way to capture a signal file is to use the GNU Radio Companion GUI. Only two blocks are needed: a USRP signal source connected to complex float file sink. You need to tune the USRP central frequency and decimation factor using USRP signal source properties box. We suggest using a decimation factor of 20 if you use the USRP2. This will give you 100/20 = 5 MSPS which will be enough to receive GPS L1 C/A signals. The front-end gain should also be configured. In our test with the DBSRX2 we obtained good results with ```G=50```.
4. Capture at least 80 seconds of signal in open sky conditions. During the process, be aware of USRP driver buffer underuns messages. If your hard disk is not fast enough to write data at this speed you can capture to a virtual RAM drive. 80 seconds of signal at 5 MSPS occupies less than 3 Gbytes using ```gr_complex<float>```.
5. If you have no access to a RF front-end, you can download a sample raw data file (that contains GPS and Galileo signals) from [here](http://sourceforge.net/projects/gnss-sdr/files/data/).
4. Capture at least 80 seconds of signal in open sky conditions. During the process, be aware of USRP driver buffer underruns messages. If your hard disk is not fast enough to write data at this speed you can capture to a virtual RAM drive. 80 seconds of signal at 5 MSPS occupies less than 3 Gbytes using ```gr_complex<float>```.
5. If you have no access to an RF front-end, you can download a sample raw data file (that contains GPS and Galileo signals) from [here](http://sourceforge.net/projects/gnss-sdr/files/data/).
3. You are ready to configure the receiver to use your captured file among other parameters:
1. The default configuration file resides at [/usr/local/share/gnss-sdr/conf/default.conf](./conf/gnss-sdr.conf).
2. You need to review/modify at least the following settings:
@ -717,7 +718,7 @@ For more information, check out our [quick start guide](http://gnss-sdr.org/quic
Using GNSS-SDR
==============
With GNSS-SDR, you can define you own receiver, work with captured raw data or from a RF front-end, dump into files intermediate signals, or tune every single algorithm used in the signal processing. All the configuration is done in a single file. Those configuration files reside at the [gnss-sdr/conf/](./conf/) folder (or at /usr/local/share/gnss-sdr/conf if you installed the program). By default, the executable ```gnss-sdr``` will read the configuration available at ```gnss-sdr/conf/gnss-sdr.conf``` (or at (usr/local/share/gnss-sdr/conf/default.conf if you installed the program). You can edit that file to fit your needs, or even better, define a new ```my_receiver.conf``` file with your own configuration. This new receiver can be generated by invoking gnss-sdr with the ```--config_file``` flag pointing to your configuration file:
With GNSS-SDR, you can define your own receiver, work with captured raw data or from an RF front-end, dump into files intermediate signals, or tune every single algorithm used in the signal processing. All the configuration is done in a single file. Those configuration files reside at the [gnss-sdr/conf/](./conf/) folder (or at /usr/local/share/gnss-sdr/conf if you installed the program). By default, the executable ```gnss-sdr``` will read the configuration available at ```gnss-sdr/conf/gnss-sdr.conf``` (or at (usr/local/share/gnss-sdr/conf/default.conf if you installed the program). You can edit that file to fit your needs, or even better, define a new ```my_receiver.conf``` file with your own configuration. This new receiver can be generated by invoking gnss-sdr with the ```--config_file``` flag pointing to your configuration file:
~~~~~~
$ gnss-sdr --config_file=/path/to/my_receiver.conf
@ -769,7 +770,7 @@ Since the configuration is just a set of property names and values without any m
### GNSS block factory
Hence, the application defines a simple accessor class to fetch the configuration pairs of values and passes them to a factory class called [GNSSBlockFactory](./src/core/receiver/gnss_block_factory.h). This factory decides, according to the configuration, which class needs to be instantiated and which parameters should be passed to the constructor. Hence, the factory encapsulates the complexity of blocks' instantiation. With that approach, adding a new block that requires new parameters will be as simple as adding the block class and modifying the factory to be able to instantiate it. This loose coupling between the blocks' implementations and the syntax of the configuration enables extending the application capacities in a high degree. It also allows to produce fully customized receivers, for instance a testbed for acquisition algorithms, and to place observers at any point of the receiver chain.
Hence, the application defines a simple accessor class to fetch the configuration pairs of values and passes them to a factory class called [GNSSBlockFactory](./src/core/receiver/gnss_block_factory.h). This factory decides, according to the configuration, which class needs to be instantiated and which parameters should be passed to the constructor. Hence, the factory encapsulates the complexity of blocks' instantiation. With that approach, adding a new block that requires new parameters will be as simple as adding the block class and modifying the factory to be able to instantiate it. This loose coupling between the blocks' implementations and the syntax of the configuration enables extending the application capacities in a high degree. It also allows producing fully customized receivers, for instance a testbed for acquisition algorithms, and to place observers at any point of the receiver chain.
More information can be found at the [Control Plane page](http://gnss-sdr.org/docs/control-plane/).
@ -783,9 +784,9 @@ GNU Radio's class ```gr::basic_block``` is the abstract base class for all signa
A signal processing flow is constructed by creating a tree of hierarchical blocks, which at any level may also contain terminal nodes that actually implement signal processing functions.
Class ```gr::top_block``` is the top-level hierarchical block representing a flowgraph. It defines GNU Radio runtime functions used during the execution of the program: run(), start(), stop(), wait(), etc. A a subclass called [GNSSBlockInterface](./src/core/interfaces/gnss_block_interface.h) is the common interface for all the GNSS-SDR modules. It defines pure virtual methods, that are required to be implemented by a derived class.
Class ```gr::top_block``` is the top-level hierarchical block representing a flowgraph. It defines GNU Radio runtime functions used during the execution of the program: run(), start(), stop(), wait(), etc. A subclass called [GNSSBlockInterface](./src/core/interfaces/gnss_block_interface.h) is the common interface for all the GNSS-SDR modules. It defines pure virtual methods, that are required to be implemented by a derived class.
Subclassing GNSSBlockInterface, we defined interfaces for the GNSS receiver blocks depicted in the figure above. This hierarchy provides the definition of different algorithms and different implementations, which will be instantiated according to the configuration. This strategy allows multiple implementations sharing a common interface, achieving the objective of decoupling interfaces from implementations: it defines a family of algorithms, encapsulates each one, and makes them interchangeable. Hence, we let the algorithm vary independently from the program that uses it.
Subclassing GNSSBlockInterface, we defined interfaces for the GNSS receiver blocks depicted in the figure above. This hierarchy provides the definition of different algorithms and different implementations, which will be instantiated according to the configuration. This strategy allows multiple implementations sharing a common interface, achieving the objective of decoupling interfaces from implementations: it defines a family of algorithms, encapsulates each one, and makes them interchangeable. Hence, we let the algorithm vary independently of the program that uses it.
Internally, GNSS-SDR makes use of the complex data types defined by [VOLK](http://libvolk.org/ "Vector-Optimized Library of Kernels home"). They are fundamental for handling sample streams in which samples are complex numbers with real and imaginary components of 8, 16 or 32 bits, common formats delivered by GNSS (and generic SDR) radio frequency front-ends. The following list shows the data type names that GNSS-SDR exposes through the configuration file:
@ -805,7 +806,7 @@ More information about the available processing blocks and their configuration p
The input of a software receiver are the raw bits that come out from the front-end's analog-to-digital converter (ADC). Those bits can be read from a file stored in the hard disk or directly in real-time from a hardware device through USB or Ethernet buses.
The Signal Source module is in charge of implementing the hardware driver, that is, the portion of the code that communicates with the RF front-end and receives the samples coming from the ADC. This communication is usually performed through USB or Ethernet buses. Since real-time processing requires a highly optimized implementation of the whole receiver, this module also allows to read samples from a file stored in a hard disk, and thus processing without time constraints. Relevant parameters of those samples are the intermediate frequency (or baseband I&Q components), the sampling rate and number of bits per sample, that must be specified by the user in the configuration file.
The Signal Source module is in charge of implementing the hardware driver, that is, the portion of the code that communicates with the RF front-end and receives the samples coming from the ADC. This communication is usually performed through USB or Ethernet buses. Since real-time processing requires a highly optimized implementation of the whole receiver, this module also allows reading samples from a file stored in a hard disk, and thus processing without time constraints. Relevant parameters of those samples are the intermediate frequency (or baseband I&Q components), the sampling rate and number of bits per sample, that must be specified by the user in the configuration file.
This module also performs bit-depth adaptation, since most of the existing RF front-ends provide samples quantized with 2 or 3 bits, while operations inside the processor are performed on 32- or 64-bit words, depending on its architecture. Although there are implementations of the most intensive computational processes (mainly correlation) that take advantage of specific data types and architectures for the sake of efficiency, the approach is processor-specific and hardly portable. We suggest to keep signal samples in standard data types and letting the compiler select the best library version (implemented using SIMD or any other processor-specific technology) of the required routines for a given processor.
@ -821,7 +822,7 @@ SignalSource.item_type=gr_complex
SignalSource.sampling_frequency=4000000 ; Sampling frequency in samples per second (Sps)
~~~~~~
Type ```gr_complex``` refers to a GNU Radio typedef equivalent to ```std::complex<float>```. In order to save some storage space, you might wanted to store your signal in a more efficient format such as an I/Q interleaved ```short`` integer sample stream. In that case, change the corresponding line to:
Type ```gr_complex``` refers to a GNU Radio typedef equivalent to ```std::complex<float>```. In order to save some storage space, you might want to store your signal in a more efficient format such as an I/Q interleaved ```short`` integer sample stream. In that case, change the corresponding line to:
~~~~~~
SignalSource.item_type=ishort
@ -845,7 +846,7 @@ Sometimes, samples are stored in files with a format which is not in the list of
Within a byte the samples may be packed in big endian ```big_endian_bytes=true``` (if the most significant byte value is stored at the memory location with the lowest address, the next byte value in significance is stored at the following memory location, and so on) or little endian ```big_endian_bytes=false``` (if the least significant byte value is at the lowest address, and the other bytes follow in increasing order of significance). If the order is big endian then the most significant two bits will form the first sample output, otherwise the least significant two bits will be used.
Additionally the samples may be either real ```sample_type=real```, or complex. If the sample type is complex, then the samples are either stored in the order: real, imag, real, imag, ... ```sample_type=iq``` or in the order: imag, real, imag, real, ... ```sample_type=qi```.
Additionally, the samples may be either real ```sample_type=real```, or complex. If the sample type is complex, then the samples are either stored in the order: real, imag, real, imag, ... ```sample_type=iq``` or in the order: imag, real, imag, real, ... ```sample_type=qi```.
Finally, if the data is stored as shorts ```item_type=short```, then it may be stored in either big endian ```big_endian_items=true``` or little endian ```big_endian_items=false```. If the shorts are big endian then the 2nd byte in each short is output first.
@ -1007,7 +1008,7 @@ If your signal source is providing baseband signal samples of type ```gr_complex
SignalConditioner.implementation=Pass_Through
~~~~~~
If you need to adapt some aspect of you signal, you can enable the Signal Conditioner and configure three internal blocks: a data type adpater, an input signal and a resampler.
If you need to adapt some aspect of your signal, you can enable the Signal Conditioner and configure three internal blocks: a data type adapter, an input signal and a resampler.
~~~~~~
;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks
@ -1030,7 +1031,7 @@ More documentation at the [Data Type Adapter Blocks page](http://gnss-sdr.org/do
#### Input filter
This block filters the input data. It can be combined with frequency translation for IF signals. The computation of the filter taps is based on parameters of GNU Radio's function [pm_remez](http://gnuradio.org/doc/doxygen/pm__remez_8h.html), that calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands.
This block filters the input data. It can be combined with frequency translation for IF signals. The computation of the filter taps is based on parameters of GNU Radio's function [pm_remez](http://gnuradio.org/doc/doxygen/pm__remez_8h.html), that calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, the desired response on those bands, and the weight given to the error in those bands.
The block can be configured like this:
@ -1085,7 +1086,7 @@ More documentation at the [Input Filter Blocks page](http://gnss-sdr.org/docs/sp
#### Resampler
This block resamples the input data stream. The ```Direct_Resampler``` block implements a nearest neigbourhood interpolation:
This block resamples the input data stream. The ```Direct_Resampler``` block implements a nearest neighbourhood interpolation:
~~~~~~
;######### RESAMPLER CONFIG ############
@ -1103,7 +1104,7 @@ More documentation at the [Resampler Blocks page](http://gnss-sdr.org/docs/sp-bl
### Channel
A channel encapsulates all signal processing devoted to a single satellite. Thus, it is a large composite object which encapsulates the acquisition, tracking and navigation data decoding modules. As a composite object, it can be treated as a single entity, meaning that it can be easily replicated. Since the number of channels is selectable by the user in the configuration file, this approach helps improving the scalability and maintainability of the receiver.
A channel encapsulates all signal processing devoted to a single satellite. Thus, it is a large composite object which encapsulates the acquisition, tracking and navigation data decoding modules. As a composite object, it can be treated as a single entity, meaning that it can be easily replicated. Since the number of channels is selectable by the user in the configuration file, this approach helps to improve the scalability and maintainability of the receiver.
Each channel must be assigned to a GNSS signal, according to the following identifiers:
@ -1113,6 +1114,7 @@ Each channel must be assigned to a GNSS signal, according to the following ident
| Galileo E1b/c | 1B |
| Glonass L1 C/A | 1G |
| GPS L2 L2C(M) | 2S |
| Glonass L2 C/A | 2G |
| GPS L5 | L5 |
| Galileo E5a | 5X |
@ -1144,7 +1146,7 @@ Channel6.signal=1B ;
Channel7.signal=1B ;
~~~~~~
This module is also in charge of managing the interplay between acquisition and tracking. Acquisition can be initialized in several ways, depending on the prior information available (called cold start when the receiver has no information about its position nor the satellites almanac; warm start when a rough location and the approximate time of day are available, and the receiver has a recently recorded almanac broadcast; or hot start when the receiver was tracking a satellite and the signal line of sight broke for a short period of time, but the ephemeris and almanac data is still valid, or this information is provided by other means), and an acquisition process can finish deciding that the satellite is not present, that longer integration is needed in order to confirm the presence of the satellite, or declaring the satellite present. In the latter case, acquisition process should stop and trigger the tracking module with coarse estimations of the synchronization parameters. The mathematical abstraction used to design this logic is known as finite state machine (FSM), that is a behavior model composed of a finite number of states, transitions between those states, and actions. For the implementation, we use the [Boost.Statechart library](http://www.boost.org/libs/statechart/doc/tutorial.html), which provides desirable features such as support for asynchronous state machines, multi-threading, type-safety, error handling and compile-time validation.
This module is also in charge of managing the interplay between acquisition and tracking. Acquisition can be initialized in several ways, depending on the prior information available (called cold start when the receiver has no information about its position nor the satellites' almanac; warm start when a rough location and the approximate time of day are available, and the receiver has a recently recorded almanac broadcast; or hot start when the receiver was tracking a satellite and the signal line of sight broke for a short period of time, but the ephemeris and almanac data is still valid, or this information is provided by other means), and an acquisition process can finish deciding that the satellite is not present, that longer integration is needed in order to confirm the presence of the satellite, or declaring the satellite present. In the latter case, acquisition process should stop and trigger the tracking module with coarse estimations of the synchronization parameters. The mathematical abstraction used to design this logic is known as finite state machine (FSM), that is a behavior model composed of a finite number of states, transitions between those states, and actions.
The abstract class [ChannelInterface](./src/core/interfaces/channel_interface.h) represents an interface to a channel GNSS block. Check [Channel](./src/algorithms/channel/adapters/channel.h) for an actual implementation.
@ -1254,7 +1256,7 @@ More documentation at the [Tracking Blocks page](http://gnss-sdr.org/docs/sp-blo
#### Decoding of the navigation message
Most of GNSS signal links are modulated by a navigation message containing the time the message was transmitted, orbital parameters of satellites (also known as ephemeris) and an almanac (information about the general system health, rough orbits of all satellites in the network as well as data related to error correction). Navigation data bits are structured in words, pages, subframes, frames and superframes. Sometimes, bits corresponding to a single parameter are spread over different words, and values extracted from different frames are required for proper decoding. Some words are for synchronization purposes, others for error control an others contain actual information. There are also error control mechanisms, from parity checks to forward error correction (FEC) encoding and interleaving, depending on the system. All this decoding complexity is managed by a finite state machine implemented with the [Boost.Statechart library](http://www.boost.org/libs/statechart/doc/tutorial.html).
Most of GNSS signal links are modulated by a navigation message containing the time the message was transmitted, orbital parameters of satellites (also known as ephemeris) and an almanac (information about the general system health, rough orbits of all satellites in the network as well as data related to error correction). Navigation data bits are structured in words, pages, subframes, frames and superframes. Sometimes, bits corresponding to a single parameter are spread over different words, and values extracted from different frames are required for proper decoding. Some words are for synchronization purposes, others for error control and others contain actual information. There are also error control mechanisms, from parity checks to forward error correction (FEC) encoding and interleaving, depending on the system. All this decoding complexity is managed by a finite state machine.
The common interface is [TelemetryDecoderInterface](./src/core/interfaces/telemetry_decoder_interface.h). Check [GpsL1CaTelemetryDecoder](./src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.h) for an example of the GPS L1 NAV message decoding adapter, and [gps_l1_ca_telemetry_decoder_cc](./src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.h) for an actual implementation of a signal processing block. Configuration example:
@ -1341,7 +1343,7 @@ PVT.rtcm_MT1077_rate_ms=1000
PVT.rinex_version=2
~~~~~~
* **RTCM SC-104** provides standards that define the data structure for differential GNSS correction information for a variety of differential correction applications. Developed by the Radio Technical Commission for Maritime Services ([RTCM](http://www.rtcm.org/overview.php#Standards "Radio Technical Commission for Maritime Services")), they have become an industry standard for communication of correction information. GNSS-SDR implements RTCM version 3.2, defined in the document *RTCM 10403.2, Differential GNSS (Global Navigation Satellite Systems) Services - Version 3* (February 1, 2013), which can be [purchased online](https://ssl29.pair.com/dmarkle/puborder.php?show=3 "RTCM Online Publication Order Form"). By default, the generated RTCM binary messages are dumped into a text file in hexadecimal format. However, GNSS-SDR is equipped with a TCP/IP server, acting as an NTRIP source that can feed an NTRIP server. NTRIP (Networked Transport of RTCM via Internet Protocol) is an open standard protocol that can be freely download from [BKG](http://igs.bkg.bund.de/root_ftp/NTRIP/documentation/NtripDocumentation.pdf "Networked Transport of RTCM via Internet Protocol (Ntrip) Version 1.0"), and it is designed for disseminating differential correction data (*e.g.* in the RTCM-104 format) or other kinds of GNSS streaming data to stationary or mobile users over the Internet. The TCP/IP server can be enabled by setting ```PVT.flag_rtcm_server=true``` in the configuration file, and will be active during the execution of the software receiver. By default, the server will operate on port 2101 (which is the recommended port for RTCM services according to the Internet Assigned Numbers Authority, [IANA](http://www.iana.org/assignments/service-names-port-numbers "Service Name and Transport Protocol Port Number Registry")), and will identify the Reference Station with ID=1234. This behaviour can be changed in the configuration file:
* **RTCM SC-104** provides standards that define the data structure for differential GNSS correction information for a variety of differential correction applications. Developed by the Radio Technical Commission for Maritime Services ([RTCM](http://www.rtcm.org/overview.php#Standards "Radio Technical Commission for Maritime Services")), they have become an industry standard for communication of correction information. GNSS-SDR implements RTCM version 3.2, defined in the document *RTCM 10403.2, Differential GNSS (Global Navigation Satellite Systems) Services - Version 3* (February 1, 2013), which can be [purchased online](https://ssl29.pair.com/dmarkle/puborder.php?show=3 "RTCM Online Publication Order Form"). By default, the generated RTCM binary messages are dumped into a text file in hexadecimal format. However, GNSS-SDR is equipped with a TCP/IP server, acting as an NTRIP source that can feed an NTRIP server. NTRIP (Networked Transport of RTCM via Internet Protocol) is an open standard protocol that can be freely downloaded from [BKG](http://igs.bkg.bund.de/root_ftp/NTRIP/documentation/NtripDocumentation.pdf "Networked Transport of RTCM via Internet Protocol (Ntrip) Version 1.0"), and it is designed for disseminating differential correction data (*e.g.* in the RTCM-104 format) or other kinds of GNSS streaming data to stationary or mobile users over the Internet. The TCP/IP server can be enabled by setting ```PVT.flag_rtcm_server=true``` in the configuration file, and will be active during the execution of the software receiver. By default, the server will operate on port 2101 (which is the recommended port for RTCM services according to the Internet Assigned Numbers Authority, [IANA](http://www.iana.org/assignments/service-names-port-numbers "Service Name and Transport Protocol Port Number Registry")), and will identify the Reference Station with ID=1234. This behaviour can be changed in the configuration file:
~~~~~~
PVT.flag_rtcm_server=true
PVT.rtcm_tcp_port=2102
@ -1398,9 +1400,9 @@ There is a list of papers related to GNSS-SDR in our [publications page](http://
Ok, now what?
=============
In order to start using GNSS-SDR, you may want to populate ```gnss-sdr/data``` folder (or anywhere else on your system) with raw data files. By "raw data" we mean the output of a Radio Frequency front-end's Analog-to-Digital converter. GNSS-SDR needs signal samples already in baseband or in passband, at a suitable intemediate frequency (on the order of MHz). Prepare your configuration file, and then you are ready for running ```gnss-sdr --config_file=your_configuration.conf```, and seeing how the file is processed.
In order to start using GNSS-SDR, you may want to populate ```gnss-sdr/data``` folder (or anywhere else on your system) with raw data files. By "raw data" we mean the output of a Radio Frequency front-end's Analog-to-Digital converter. GNSS-SDR needs signal samples already in baseband or in passband, at a suitable intermediate frequency (on the order of MHz). Prepare your configuration file, and then you are ready for running ```gnss-sdr --config_file=your_configuration.conf```, and seeing how the file is processed.
Another interesting option is working in real-time with a RF front-end. We provide drivers for UHD-compatible hardware such as the [USRP family](http://www.ettus.com/product), for OsmoSDR and other front-ends (HackRF, bladeRF, LimeSDR), for the GN3S v2 USB dongle and for some DVB-T USB dongles. Start with a low number of channels and then increase it in order to test how many channels your processor can handle in real-time.
Another interesting option is working in real-time with an RF front-end. We provide drivers for UHD-compatible hardware such as the [USRP family](http://www.ettus.com/product), for OsmoSDR and other front-ends (HackRF, bladeRF, LimeSDR), for the GN3S v2 USB dongle and for some DVB-T USB dongles. Start with a low number of channels and then increase it in order to test how many channels your processor can handle in real-time.
You can find more information at the [GNSS-SDR Documentation page](http://gnss-sdr.org/docs/) or directly asking to the [GNSS-SDR Developers mailing list](http://lists.sourceforge.net/lists/listinfo/gnss-sdr-developers).

View File

@ -5,17 +5,18 @@ FIND_PATH(
LIBIIO_INCLUDE_DIRS
NAMES gnuradio/iio/api.h
HINTS $ENV{LIBIIO_DIR}/include
${PC_LIBIIO_INCLUDEDIR}
${PC_LIBIIO_INCLUDEDIR}
PATHS ${CMAKE_INSTALL_PREFIX}/include
/usr/local/include
/usr/include
/opt/local/include
)
FIND_LIBRARY(
LIBIIO_LIBRARIES
NAMES libiio.so
NAMES libiio.so iio
HINTS $ENV{LIBIIO_DIR}/lib
${PC_LIBIIO_LIBDIR}
${PC_LIBIIO_LIBDIR}
PATHS ${CMAKE_INSTALL_PREFIX}/lib
${CMAKE_INSTALL_PREFIX}/lib64
/usr/local/lib
@ -23,10 +24,30 @@ FIND_LIBRARY(
/usr/lib
/usr/lib64
/usr/lib/x86_64-linux-gnu
/usr/lib/gcc/alpha-linux-gnu
/usr/lib/gcc/aarch64-linux-gnu
/usr/lib/gcc/arm-linux-gnueabi
/usr/lib/gcc/arm-linux-gnueabihf
/usr/lib/gcc/hppa-linux-gnu
/usr/lib/gcc/i686-gnu
/usr/lib/gcc/i686-linux-gnu
/usr/lib/gcc/x86_64-kfreebsd-gnu
/usr/lib/gcc/i686-kfreebsd-gnu
/usr/lib/gcc/m68k-linux-gnu
/usr/lib/gcc/mips-linux-gnu
/usr/lib/gcc/mips64el-linux-gnuabi64
/usr/lib/gcc/mipsel-linux-gnu
/usr/lib/gcc/powerpc-linux-gnu
/usr/lib/gcc/powerpc-linux-gnuspe
/usr/lib/gcc/powerpc64-linux-gnu
/usr/lib/gcc/powerpc64le-linux-gnu
/usr/lib/gcc/s390x-linux-gnu
/usr/lib/gcc/sparc64-linux-gnu
/usr/lib/gcc/x86_64-linux-gnux32
/usr/lib/gcc/sh4-linux-gnu
/Library/Frameworks/iio.framework/
)
message("find libiio:")
message(${LIBIIO_LIBRARIES})
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBIIO DEFAULT_MSG LIBIIO_LIBRARIES LIBIIO_INCLUDE_DIRS)
MARK_AS_ADVANCED(LIBIIO_LIBRARIES LIBIIO_INCLUDE_DIRS)

View File

@ -138,4 +138,4 @@ PVT.rtcm_MT1019_rate_ms=5000
PVT.rtcm_MT1045_rate_ms=5000
PVT.rtcm_MT1097_rate_ms=1000
PVT.rtcm_MT1077_rate_ms=1000
PVT.rinex_version=3
PVT.rinex_version=2

View File

@ -5,7 +5,7 @@ GNSS-SDR.internal_fs_sps=6625000
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=File_Signal_Source
SignalSource.filename=/archive/NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE
SignalSource.filename=/media/dmiralles/Seagate Backup Plus Drive/GNSS Data/NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE ; <- PUT YOUR FILE HERE
SignalSource.item_type=ibyte
SignalSource.sampling_frequency=6625000
SignalSource.samples=0
@ -25,11 +25,11 @@ Channel.signal=1G
Channels.in_acquisition=1
Channels_1G.count=5
;Channel0.satellite=24 ; k=
;Channel1.satellite=1 ; k=1
;Channel2.satellite=2 ; k=-4
;Channel3.satellite=20 ; k=-5
;Channel4.satellite=21 ; k=4
Channel0.satellite=24 ; k=
Channel1.satellite=1 ; k=1
Channel2.satellite=2 ; k=-4
Channel3.satellite=20 ; k=-5
Channel4.satellite=21 ; k=4
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_1G.implementation=GLONASS_L1_CA_PCPS_Acquisition
@ -39,7 +39,7 @@ Acquisition_1G.pfa=0.0001
Acquisition_1G.if=0
Acquisition_1G.doppler_max=10000
Acquisition_1G.doppler_step=250
Acquisition_1G.dump=false;
Acquisition_1G.dump=true;
Acquisition_1G.dump_filename=/archive/glo_acquisition.dat
;Acquisition_1G.coherent_integration_time_ms=1
;Acquisition_1G.max_dwells = 5
@ -51,7 +51,7 @@ Tracking_1G.if=0
Tracking_1G.early_late_space_chips=0.5
Tracking_1G.pll_bw_hz=25.0;
Tracking_1G.dll_bw_hz=3.0;
Tracking_1G.dump=false;
Tracking_1G.dump=true;
Tracking_1G.dump_filename=/archive/glo_tracking_ch_
;######### TELEMETRY DECODER GPS CONFIG ############
@ -59,7 +59,7 @@ TelemetryDecoder_1G.implementation=GLONASS_L1_CA_Telemetry_Decoder
;######### OBSERVABLES CONFIG ############
Observables.implementation=Hybrid_Observables
Observables.dump=false;
Observables.dump=true;
Observables.dump_filename=/archive/glo_observables.dat
;######### PVT CONFIG ############
@ -76,4 +76,4 @@ PVT.rtcm_MT1019_rate_ms=5000
PVT.rtcm_MT1045_rate_ms=5000
PVT.rtcm_MT1097_rate_ms=1000
PVT.rtcm_MT1077_rate_ms=1000
PVT.rinex_version=3
PVT.rinex_version=2

View File

@ -0,0 +1,141 @@
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
GNSS-SDR.internal_fs_sps=6625000
Receiver.sources_count=2
;######### SIGNAL_SOURCE CONFIG ############
SignalSource0.implementation=File_Signal_Source
SignalSource0.filename=/media/dmiralles/Seagate Backup Plus Drive/GNSS Data/NT1065_L1_20160923_fs6625e6_if60e3_schar.bin ; <- PUT YOUR FILE HERE
SignalSource0.item_type=ibyte
SignalSource0.sampling_frequency=6625000
SignalSource0.samples=0
SignalSource0.dump=false;
SignalSource0.dump_filename=/archive/signal_glonass.bin
SignalSource1.implementation=File_Signal_Source
SignalSource1.filename=/media/dmiralles/Seagate Backup Plus Drive/GNSS Data/NT1065_GLONASS_L2_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE
SignalSource1.item_type=ibyte
SignalSource1.sampling_frequency=6625000
SignalSource1.samples=0
SignalSource1.dump=false;
SignalSource1.dump_filename=/archive/signal_glonass.bin
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner0.implementation=Signal_Conditioner
DataTypeAdapter0.implementation=Ibyte_To_Complex
InputFilter0.implementation=Freq_Xlating_Fir_Filter
InputFilter0.item_type=gr_complex
InputFilter0.output_item_type=gr_complex
InputFilter0.taps_item_type=float
InputFilter0.number_of_taps=5
InputFilter0.number_of_bands=2
InputFilter0.band1_begin=0.0
InputFilter0.band1_end=0.70
InputFilter0.band2_begin=0.80
InputFilter0.band2_end=1.0
InputFilter0.ampl1_begin=1.0
InputFilter0.ampl1_end=1.0
InputFilter0.ampl2_begin=0.0
InputFilter0.ampl2_end=0.0
InputFilter0.band1_error=1.0
InputFilter0.band2_error=1.0
InputFilter0.filter_type=bandpass
InputFilter0.grid_density=16
InputFilter0.sampling_frequency=6625000
InputFilter0.IF=60000
Resampler0.implementation=Direct_Resampler
Resampler0.sample_freq_in=6625000
Resampler0.sample_freq_out=6625000
Resampler0.item_type=gr_complex
SignalConditioner1.implementation=Signal_Conditioner
DataTypeAdapter1.implementation=Ibyte_To_Complex
InputFilter1.implementation=Pass_Through
InputFilter1.item_type=gr_complex
Resampler1.implementation=Pass_Through
Resampler1.item_type=gr_complex
;######### CHANNELS GLOBAL CONFIG ############
Channels.in_acquisition=1
Channels_2G.count=5
Channels_1C.count=5
;# Defining GLONASS satellites
Channel0.RF_channel_ID=0
Channel1.RF_channel_ID=0
Channel2.RF_channel_ID=0
Channel3.RF_channel_ID=0
Channel4.RF_channel_ID=0
Channel5.RF_channel_ID=1
Channel6.RF_channel_ID=1
Channel7.RF_channel_ID=1
Channel8.RF_channel_ID=1
Channel9.RF_channel_ID=1
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
Acquisition_1C.item_type=gr_complex
Acquisition_1C.threshold=0.0
Acquisition_1C.pfa=0.00001
Acquisition_1C.if=0
Acquisition_1C.doppler_max=10000
Acquisition_1C.doppler_step=250
Acquisition_1C.dump=false;
Acquisition_1C.dump_filename=/archive/gps_acquisition.dat
;Acquisition_1C.coherent_integration_time_ms=10
Acquisition_2G.implementation=GLONASS_L2_CA_PCPS_Acquisition
Acquisition_2G.item_type=gr_complex
Acquisition_2G.threshold=0.0
Acquisition_2G.pfa=0.00001
Acquisition_2G.if=0
Acquisition_2G.doppler_max=10000
Acquisition_2G.doppler_step=250
Acquisition_2G.dump=false;
Acquisition_2G.dump_filename=/archive/glo_acquisition.dat
;Acquisition_2G.coherent_integration_time_ms=10
;######### TRACKING GLOBAL CONFIG ############
Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
Tracking_1C.item_type=gr_complex
Tracking_1C.if=0
Tracking_1C.early_late_space_chips=0.5
Tracking_1C.pll_bw_hz=20.0;
Tracking_1C.dll_bw_hz=2.0;
Tracking_1C.dump=false;
Tracking_1C.dump_filename=/archive/gps_tracking_ch_
Tracking_2G.implementation=GLONASS_L2_CA_DLL_PLL_Tracking
Tracking_2G.item_type=gr_complex
Tracking_2G.if=0
Tracking_2G.early_late_space_chips=0.5
Tracking_2G.pll_bw_hz=25.0;
Tracking_2G.dll_bw_hz=2.0;
Tracking_2G.dump=false;
Tracking_2G.dump_filename=/archive/glo_tracking_ch_
;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
TelemetryDecoder_2G.implementation=GLONASS_L2_CA_Telemetry_Decoder
;######### OBSERVABLES CONFIG ############
Observables.implementation=Hybrid_Observables
Observables.dump=false;
Observables.dump_filename=/archive/gnss_observables.dat
;######### PVT CONFIG ############
PVT.implementation=RTKLIB_PVT
PVT.output_rate_ms=100
PVT.display_rate_ms=500
PVT.trop_model=Saastamoinen
PVT.flag_rtcm_server=false
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1
PVT.rtcm_tcp_port=2101
PVT.rtcm_MT1019_rate_ms=5000
PVT.rtcm_MT1045_rate_ms=5000
PVT.rtcm_MT1097_rate_ms=1000
PVT.rtcm_MT1077_rate_ms=1000
PVT.rinex_version=2

View File

@ -0,0 +1,142 @@
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
GNSS-SDR.internal_fs_sps=6625000
Receiver.sources_count=2
;######### SIGNAL_SOURCE CONFIG ############
SignalSource0.implementation=File_Signal_Source
SignalSource0.filename=/archive/NT1065_L2_20160923_fs6625e6_if60e3_schar.bin ; <- PUT YOUR FILE HERE
SignalSource0.item_type=ibyte
SignalSource0.sampling_frequency=6625000
SignalSource0.samples=0
SignalSource0.dump=false;
SignalSource0.dump_filename=/archive/signal_glonass.bin
SignalSource1.implementation=File_Signal_Source
SignalSource1.filename=/archive/NT1065_GLONASS_L2_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE
SignalSource1.item_type=ibyte
SignalSource1.sampling_frequency=6625000
SignalSource1.samples=0
SignalSource1.dump=false;
SignalSource1.dump_filename=/archive/signal_glonass.bin
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner0.implementation=Signal_Conditioner
DataTypeAdapter0.implementation=Ibyte_To_Complex
InputFilter0.implementation=Freq_Xlating_Fir_Filter
InputFilter0.item_type=gr_complex
InputFilter0.output_item_type=gr_complex
InputFilter0.taps_item_type=float
InputFilter0.number_of_taps=5
InputFilter0.number_of_bands=2
InputFilter0.band1_begin=0.0
InputFilter0.band1_end=0.70
InputFilter0.band2_begin=0.80
InputFilter0.band2_end=1.0
InputFilter0.ampl1_begin=1.0
InputFilter0.ampl1_end=1.0
InputFilter0.ampl2_begin=0.0
InputFilter0.ampl2_end=0.0
InputFilter0.band1_error=1.0
InputFilter0.band2_error=1.0
InputFilter0.filter_type=bandpass
InputFilter0.grid_density=16
InputFilter0.sampling_frequency=6625000
InputFilter0.IF=60000
Resampler0.implementation=Pass_Through
Resampler0.item_type=gr_complex
SignalConditioner1.implementation=Signal_Conditioner
DataTypeAdapter1.implementation=Ibyte_To_Complex
InputFilter1.implementation=Pass_Through
InputFilter1.item_type=gr_complex
Resampler1.implementation=Pass_Through
Resampler1.item_type=gr_complex
;######### CHANNELS GLOBAL CONFIG ############
Channels.in_acquisition=5
Channels_2S.count=5
Channels_2G.count=5
;# Defining GLONASS satellites
Channel0.RF_channel_ID=0
Channel0.signal=2S
Channel1.RF_channel_ID=0
Channel1.signal=2S
Channel2.RF_channel_ID=0
Channel2.signal=2S
Channel3.RF_channel_ID=0
Channel3.signal=2S
Channel4.RF_channel_ID=0
Channel4.signal=2S
Channel5.RF_channel_ID=1
Channel6.RF_channel_ID=1
Channel7.RF_channel_ID=1
Channel8.RF_channel_ID=1
Channel9.RF_channel_ID=1
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition
Acquisition_2S.item_type=gr_complex
Acquisition_2S.threshold=0.0
Acquisition_2S.pfa=0.00001
Acquisition_2S.if=0
Acquisition_2S.doppler_max=10000
Acquisition_2S.doppler_step=60
Acquisition_2S.max_dwells=1
Acquisition_2G.implementation=GLONASS_L2_CA_PCPS_Acquisition
Acquisition_2G.item_type=gr_complex
Acquisition_2G.threshold=0.0
Acquisition_2G.pfa=0.00001
Acquisition_2G.if=0
Acquisition_2G.doppler_max=10000
Acquisition_2G.doppler_step=250
Acquisition_2G.dump=false;
Acquisition_2G.dump_filename=/archive/glo_acquisition.dat
;######### TRACKING GLOBAL CONFIG ############
Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking
Tracking_2S.item_type=gr_complex
Tracking_2S.if=0
Tracking_2S.early_late_space_chips=0.5
Tracking_2S.pll_bw_hz=2.0;
Tracking_2S.dll_bw_hz=0.250;
Tracking_2S.order=2;
Tracking_2S.dump=false;
Tracking_2S.dump_filename=/archive/gps_tracking_ch_
Tracking_2G.implementation=GLONASS_L2_CA_DLL_PLL_Tracking
Tracking_2G.item_type=gr_complex
Tracking_2G.if=0
Tracking_2G.early_late_space_chips=0.5
Tracking_2G.pll_bw_hz=25.0;
Tracking_2G.dll_bw_hz=3.0;
Tracking_2G.dump=false;
Tracking_2G.dump_filename=/archive/glo_tracking_ch_
;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_2S.implementation=GPS_L2C_Telemetry_Decoder
TelemetryDecoder_2G.implementation=GLONASS_L2_CA_Telemetry_Decoder
;######### OBSERVABLES CONFIG ############
Observables.implementation=Hybrid_Observables
Observables.dump=false;
Observables.dump_filename=/archive/gnss_observables.dat
;######### PVT CONFIG ############
PVT.implementation=RTKLIB_PVT
PVT.output_rate_ms=100
PVT.display_rate_ms=500
PVT.trop_model=Saastamoinen
PVT.flag_rtcm_server=true
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1
PVT.rtcm_tcp_port=2101
PVT.rtcm_MT1019_rate_ms=5000
PVT.rtcm_MT1045_rate_ms=5000
PVT.rtcm_MT1097_rate_ms=1000
PVT.rtcm_MT1077_rate_ms=1000
PVT.rinex_version=3

View File

@ -0,0 +1,73 @@
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
GNSS-SDR.internal_fs_sps=6625000
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=File_Signal_Source
SignalSource.filename=/media/dmiralles/Seagate Backup Plus Drive/GNSS Data/NT1065_GLONASS_L2_20160831_fs6625e6_60e3_schar_1m.bin ; <- PUT YOUR FILE HERE
SignalSource.item_type=ibyte
SignalSource.sampling_frequency=6625000
SignalSource.samples=0
SignalSource.dump=false;
SignalSource.dump_filename=/archive/signal_glonass.bin
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Signal_Conditioner
DataTypeAdapter.implementation=Ibyte_To_Complex
InputFilter.implementation=Pass_Through
InputFilter.item_type=gr_complex
Resampler.implementation=Pass_Through
Resampler.item_type=gr_complex
;######### CHANNELS GLOBAL CONFIG ############
Channel.signal=2G
Channels.in_acquisition=1
Channels_2G.count=5
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_2G.implementation=GLONASS_L2_CA_PCPS_Acquisition
Acquisition_2G.item_type=gr_complex
Acquisition_2G.threshold=0.0
Acquisition_2G.pfa=0.0001
Acquisition_2G.if=0
Acquisition_2G.doppler_max=10000
Acquisition_2G.doppler_step=250
Acquisition_2G.dump=true;
Acquisition_2G.dump_filename=/archive/glo_acquisition.dat
;Acquisition_2G.coherent_integration_time_ms=1
;Acquisition_2G.max_dwells = 5
;######### TRACKING GLOBAL CONFIG ############
Tracking_2G.implementation=GLONASS_L2_CA_DLL_PLL_Tracking
Tracking_2G.item_type=gr_complex
Tracking_2G.if=0
Tracking_2G.early_late_space_chips=0.5
Tracking_2G.pll_bw_hz=20.0;
Tracking_2G.dll_bw_hz=2.0;
Tracking_2G.dump=true;
Tracking_2G.dump_filename=/archive/glo_tracking_ch_
;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_2G.implementation=GLONASS_L2_CA_Telemetry_Decoder
;######### OBSERVABLES CONFIG ############
Observables.implementation=Hybrid_Observables
Observables.dump=true;
Observables.dump_filename=/archive/glo_observables.dat
;######### PVT CONFIG ############
PVT.implementation=RTKLIB_PVT
PVT.positioning_mode=Single
PVT.output_rate_ms=100
PVT.display_rate_ms=500
PVT.trop_model=Saastamoinen
PVT.flag_rtcm_server=false
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1
PVT.rtcm_tcp_port=2101
PVT.rtcm_MT1019_rate_ms=5000
PVT.rtcm_MT1045_rate_ms=5000
PVT.rtcm_MT1097_rate_ms=1000
PVT.rtcm_MT1077_rate_ms=1000
PVT.rinex_version=2

View File

@ -0,0 +1,83 @@
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
GNSS-SDR.internal_fs_sps=6625000
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=File_Signal_Source
SignalSource.filename=/archive/NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE
SignalSource.item_type=ibyte
SignalSource.sampling_frequency=6625000
SignalSource.samples=0
SignalSource.dump=false;
SignalSource.dump_filename=/archive/signal_glonass.bin
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Signal_Conditioner
DataTypeAdapter.implementation=Ibyte_To_Complex
InputFilter.implementation=Pass_Through
InputFilter.item_type=gr_complex
Resampler.implementation=Pass_Through
Resampler.item_type=gr_complex
;######### CHANNELS GLOBAL CONFIG ############
Channel.signal=1G
Channels.in_acquisition=2
Channels_1G.count=8
;Channel0.satellite=24 ; k=2
;Channel1.satellite=1 ; k=1
;Channel2.satellite=2 ; k=-4
;Channel3.satellite=20 ; k=-5
;Channel4.satellite=21 ; k=4
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_1G.implementation=GLONASS_L1_CA_PCPS_Acquisition
Acquisition_1G.item_type=gr_complex
Acquisition_1G.threshold=0.0
Acquisition_1G.pfa=0.0001
Acquisition_1G.if=0
Acquisition_1G.doppler_max=10000
Acquisition_1G.doppler_step=250
Acquisition_1G.dump=false;
Acquisition_1G.dump_filename=/archive/glo_acquisition.dat
;Acquisition_1G.coherent_integration_time_ms=1
;Acquisition_1G.max_dwells = 5
;######### TRACKING GLOBAL CONFIG ############
Tracking_1G.implementation=GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking
Tracking_1G.item_type=gr_complex
Tracking_1G.if=0
Tracking_1G.early_late_space_chips=0.5
Tracking_1G.pll_bw_hz=40.0;
Tracking_1G.dll_bw_hz=3.0;
Tracking_1G.pll_bw_narrow_hz = 25.0;
Tracking_1G.dll_bw_narrow_hz = 2.0;
Tracking_1G.extend_correlation_ms = 1;
Tracking_1G.dump=false;
Tracking_1G.dump_filename=/archive/glo_tracking_ch_
;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_1G.implementation=GLONASS_L1_CA_Telemetry_Decoder
;######### OBSERVABLES CONFIG ############
Observables.implementation=Hybrid_Observables
Observables.dump=false
Observables.dump_filename=/archive/glo_observables.dat
;######### PVT CONFIG ############
PVT.implementation=RTKLIB_PVT
PVT.positioning_mode=Single
PVT.output_rate_ms=100
PVT.display_rate_ms=500
PVT.trop_model=Saastamoinen
PVT.flag_rtcm_server=true
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1
PVT.rtcm_tcp_port=2101
PVT.rtcm_MT1019_rate_ms=5000
PVT.rtcm_MT1045_rate_ms=5000
PVT.rtcm_MT1097_rate_ms=1000
PVT.rtcm_MT1077_rate_ms=1000
PVT.rinex_version=2

View File

@ -0,0 +1,112 @@
; You can define your own receiver and invoke it by doing
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
;
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [Sps].
GNSS-SDR.internal_fs_sps=7000000
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=Fmcomms2_Signal_Source
SignalSource.item_type=gr_complex
SignalSource.device_address=192.168.0.4
SignalSource.sampling_frequency=7000000
SignalSource.freq=1575420000
SignalSource.bandwidth=4000000
SignalSource.RF_channels=2
SignalSource.rx1_enable=true
SignalSource.rx2_enable=true
SignalSource.gain_mode_rx1=slow_attack
SignalSource.gain_mode_rx2=slow_attack
SignalSource.rf_port_select=A_BALANCED
SignalSource.gain_rx1=64
SignalSource.gain_rx2=64
SignalSource.samples=0
SignalSource.repeat=false
SignalSource.dump=false
SignalSource.dump_filename=../data/signal_source.dat
SignalSource.enable_throttle_control=false
SignalSource.enable_dds_lo=false
SignalSource.freq_rf_tx_hz=1260000000
SignalSource.freq_dds_tx_hz=1000
SignalSource.scale_dds_dbfs=0.0
SignalSource.phase_dds_deg=0.0
SignalSource.tx_attenuation_db=0.0
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner0.implementation=Pass_Through
SignalConditioner1.implementation=Pass_Through
;######### CHANNELS GLOBAL CONFIG ############
Channels_1C.count=8
Channels.in_acquisition=1
;# CHANNEL CONNECTION
Channel0.RF_channel_ID=0
Channel0.signal=1C
Channel1.RF_channel_ID=0
Channel1.signal=1C
Channel2.RF_channel_ID=0
Channel2.signal=1C
Channel3.RF_channel_ID=0
Channel3.signal=1C
Channel4.RF_channel_ID=1
Channel4.signal=1C
Channel5.RF_channel_ID=1
Channel5.signal=1C
Channel6.RF_channel_ID=1
Channel6.signal=1C
Channel7.RF_channel_ID=1
Channel7.signal=1C
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
Acquisition_1C.item_type=gr_complex
Acquisition_1C.threshold=20
Acquisition_1C.use_CFAR_algorithm=false
Acquisition_1C.blocking=true
Acquisition_1C.doppler_max=10000
Acquisition_1C.doppler_step=250
Acquisition_1C.dump=false
Acquisition_1C.dump_filename=./acq_dump.dat
;######### TRACKING GLOBAL CONFIG ############
Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
Tracking_1C.item_type=gr_complex
Tracking_1C.dump=false
Tracking_1C.dump_filename=./tracking_ch_
Tracking_1C.pll_bw_hz=35.0;
Tracking_1C.dll_bw_hz=2.0;
Tracking_1C.early_late_space_chips=0.5;
;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
TelemetryDecoder_1C.dump=false
;######### OBSERVABLES CONFIG ############
Observables.implementation=Hybrid_Observables
Observables.dump=false
Observables.dump_filename=./observables.dat
;######### PVT CONFIG ############
PVT.implementation=RTKLIB_PVT
PVT.positioning_mode=Single ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic
PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX
PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad
PVT.output_rate_ms=100
PVT.display_rate_ms=500
PVT.dump_filename=./PVT
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
PVT.flag_nmea_tty_port=false;
PVT.nmea_dump_devname=/dev/pts/4
PVT.flag_rtcm_server=false
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1
PVT.dump=false

View File

@ -129,7 +129,7 @@ INLINE_INHERITED_MEMB = NO
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = YES
FULL_PATH_NAMES = NO
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user-defined part of the path. Stripping is
@ -703,7 +703,7 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH = @top_srcdir@/docs/doxygen/images/
IMAGE_PATH = @top_srcdir@/docs/doxygen/images/
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@ -791,7 +791,7 @@ REFERENCES_LINK_SOURCE = YES
# The default value is: YES.
# This tag requires that the tag SOURCE_BROWSER is set to YES.
SOURCE_TOOLTIPS = YES
SOURCE_TOOLTIPS = YES
# If the USE_HTAGS tag is set to YES then the references to source code
# will point to the HTML generated by the htags(1) tool instead of doxygen
@ -901,7 +901,7 @@ HTML_COLORSTYLE_GAMMA = 80
# page will contain the date and time when the page was generated. Setting
# this to NO can help when comparing the output of multiple runs.
HTML_TIMESTAMP = YES
HTML_TIMESTAMP = NO
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
@ -1164,7 +1164,7 @@ MATHJAX_EXTENSIONS =
# example see the documentation.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_CODEFILE =
MATHJAX_CODEFILE =
# When the SEARCHENGINE tag is enabled doxygen will generate a search box
# for the HTML output. The underlying search engine uses javascript
@ -1677,7 +1677,7 @@ DOT_FONTSIZE = 10
# different font using DOT_FONTNAME you can set the path where dot
# can find it using this tag.
DOT_FONTPATH =
DOT_FONTPATH =
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and

View File

@ -178,40 +178,44 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
int gal_E5a_count = configuration->property("Channels_5X.count", 0);
int gal_E5b_count = configuration->property("Channels_7X.count", 0);
int glo_1G_count = configuration->property("Channels_1G.count", 0);
int glo_2G_count = configuration->property("Channels_2G.count", 0);
unsigned int type_of_receiver = 0;
// *******************WARNING!!!!!!!***********
// GPS L5 only configurable for single frequency, single system at the moment!!!!!!
if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 1;
if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 2;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 3;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 4;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 5;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0)) type_of_receiver = 6;
if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 1;
if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 2;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 3;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 4;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 5;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 6;
if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 7;
if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 7;
//if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 8;
if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 9;
if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 10;
if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0)) type_of_receiver = 11;
if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 12;
if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 9;
if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 10;
if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 11;
if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 12;
//if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 13;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 14;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0)) type_of_receiver = 15;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 14;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 15;
//if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 16;
if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 17;
if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0)) type_of_receiver = 18;
if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 17;
if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 18;
//if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 19;
//if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 20;
if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 21;
if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 21;
//if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count = 0)) type_of_receiver = 22;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 23;
//if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2R_count != 0)) type_of_receiver = 24;
//if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_1G_count != 0)) type_of_receiver = 25;
if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 26;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 27;
if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 28;
if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 24;
if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count != 0)) type_of_receiver = 25;
if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 26;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 27;
if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 28;
if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 29;
if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 30;
if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 31;
//RTKLIB PVT solver options
// Settings 1
int positioning_mode = -1;
@ -236,9 +240,9 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
int num_bands = 0;
if ((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) num_bands = 1;
if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && (gps_2S_count > 0)) num_bands = 2;
if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gps_2S_count > 0) || (glo_2G_count > 0))) num_bands = 2;
if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 2;
if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && (gps_2S_count > 0) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 3;
if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gps_2S_count > 0) || (glo_2G_count > 0)) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 3;
int number_of_frequencies = configuration->property(role + ".num_bands", num_bands); /* (1:L1, 2:L1+L2, 3:L1+L2+L5) */
if ((number_of_frequencies < 1) || (number_of_frequencies > 3))
@ -321,7 +325,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
int nsys = 0;
if ((gps_1C_count > 0) || (gps_2S_count > 0) || (gps_L5_count > 0)) nsys += SYS_GPS;
if ((gal_1B_count > 0) || (gal_E5a_count > 0) || (gal_E5b_count > 0)) nsys += SYS_GAL;
if ((glo_1G_count > 0)) nsys += SYS_GLO;
if ((glo_1G_count > 0) || (glo_2G_count > 0)) nsys += SYS_GLO;
int navigation_system = configuration->property(role + ".navigation_system", nsys); /* (SYS_XXX) see src/algorithms/libs/rtklib/rtklib.h */
if ((navigation_system < 1) || (navigation_system > 255)) /* GPS: 1 SBAS: 2 GPS+SBAS: 3 Galileo: 8 Galileo+GPS: 9 GPS+SBAS+Galileo: 11 All: 255 */
{

File diff suppressed because it is too large Load Diff

View File

@ -3958,6 +3958,13 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris
out << line << std::endl;
// -------- Line MARKER NAME
line.clear();
line += Rinex_Printer::leftJustify("DEFAULT MARKER NAME", 60); // put a flag or a property,
line += Rinex_Printer::leftJustify("MARKER NAME", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- Line MARKER NUMBER / TYPE
if (version == 2)
{
line.clear();
@ -3977,14 +3984,6 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris
out << line << std::endl;
}
// -------- Line MARKER TYPE
line.clear();
line += Rinex_Printer::leftJustify("NON_GEODETIC", 20); // put a flag or a property
line += std::string(40, ' ');
line += Rinex_Printer::leftJustify("MARKER TYPE", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- Line OBSERVER / AGENCY
line.clear();
std::string username;
@ -4279,7 +4278,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris&
// -------- Line MARKER NAME
line.clear();
line += Rinex_Printer::leftJustify("DEFAULT MARKER NAME", 60); // put a flag or a property,
line += Rinex_Printer::leftJustify("MARKER TYPE", 20);
line += Rinex_Printer::leftJustify("MARKER NAME", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
@ -5998,6 +5997,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri
{
// RINEX observations timestamps are GPS timestamps.
std::string line;
double int_sec = 0;
// Avoid compiler warning
if (glonass_band.size())
@ -6008,12 +6008,12 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri
std::string timestring = boost::posix_time::to_iso_string(p_glonass_time);
//double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time));
//double gps_t = eph.sv_clock_correction(obs_time);
double glonass_t = obs_time;
std::string month(timestring, 4, 2);
std::string day(timestring, 6, 2);
std::string hour(timestring, 9, 2);
std::string minutes(timestring, 11, 2);
double utc_sec = modf(obs_time, &int_sec) + p_glonass_time.time_of_day().seconds();
if (version == 2)
{
@ -6046,12 +6046,11 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri
line += std::string(1, ' ');
line += minutes;
line += std::string(1, ' ');
double second_ = fmod(glonass_t, 60);
if (second_ < 10)
if (utc_sec < 10)
{
line += std::string(1, ' ');
}
line += Rinex_Printer::asString(second_, 7);
line += Rinex_Printer::asString(utc_sec, 7);
line += std::string(2, ' ');
// Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event
line += std::string(1, '0');
@ -6149,13 +6148,12 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri
line += minutes;
line += std::string(1, ' ');
double seconds = fmod(glonass_t, 60);
// Add extra 0 if seconds are < 10
if (seconds < 10)
if (utc_sec < 10)
{
line += std::string(1, '0');
}
line += Rinex_Printer::asString(seconds, 7);
line += Rinex_Printer::asString(utc_sec, 7);
line += std::string(2, ' ');
// Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event
line += std::string(1, '0');
@ -8324,8 +8322,8 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Glonass_Gnav_Ephe
boost::posix_time::ptime ls_time(d3, t3);
if (utc_time >= ls_time)
{
// We subtract the leap second when going from gpst to utc
utc_time = utc_time - boost::posix_time::time_duration(0, 0, fabs(GLONASS_LEAP_SECONDS[i][6]));
// We subtract the leap second when going from gpst to utc, values store as negatives
utc_time = utc_time + boost::posix_time::time_duration(0, 0, GLONASS_LEAP_SECONDS[i][6]);
break;
}
}
@ -8333,7 +8331,6 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Glonass_Gnav_Ephe
return utc_time;
}
double Rinex_Printer::get_leap_second(const Glonass_Gnav_Ephemeris& eph, const double gps_obs_time)
{
double tod = 0.0;

View File

@ -57,7 +57,7 @@
#include "glonass_gnav_navigation_message.h"
#include "GPS_L1_CA.h"
#include "Galileo_E1.h"
#include "GLONASS_L1_CA.h"
#include "GLONASS_L1_L2_CA.h"
#include "gnss_synchro.h"
#include <boost/date_time/posix_time/posix_time.hpp>
#include <string>

View File

@ -55,7 +55,7 @@
#include "rtklib_conversions.h"
#include "GPS_L1_CA.h"
#include "Galileo_E1.h"
#include "GLONASS_L1_CA.h"
#include "GLONASS_L1_L2_CA.h"
#include <glog/logging.h>
@ -132,7 +132,7 @@ bool rtklib_solver::get_PVT(const std::map<int, Gnss_Synchro>& gnss_observables_
for (gnss_observables_iter = gnss_observables_map.cbegin();
gnss_observables_iter != gnss_observables_map.cend();
gnss_observables_iter++)
gnss_observables_iter++) //CHECK INCONSISTENCY when combining GLONASS + other system
{
switch (gnss_observables_iter->second.System)
{
@ -241,6 +241,7 @@ bool rtklib_solver::get_PVT(const std::map<int, Gnss_Synchro>& gnss_observables_
gps_ephemeris_iter = gps_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (gps_ephemeris_iter != gps_ephemeris_map.cend())
{
/* By the moment, GPS L2 observables are not used in pseudorange computations if GPS L1 is available
// 2. If found, replace the existing GPS L1 ephemeris with the GPS L2 ephemeris
// (more precise!), and attach the L2 observation to the L1 observation in RTKLIB structure
for (int i = 0; i < valid_obs; i++)
@ -250,11 +251,12 @@ bool rtklib_solver::get_PVT(const std::map<int, Gnss_Synchro>& gnss_observables_
eph_data[i] = eph_to_rtklib(gps_cnav_ephemeris_iter->second);
obs_data[i + glo_valid_obs] = insert_obs_to_rtklib(obs_data[i + glo_valid_obs],
gnss_observables_iter->second,
gps_cnav_ephemeris_iter->second.i_GPS_week,
eph_data[i].week,
1); //Band 2 (L2)
break;
}
}
*/
}
else
{
@ -404,7 +406,7 @@ bool rtklib_solver::get_PVT(const std::map<int, Gnss_Synchro>& gnss_observables_
// **********************************************************************
this->set_valid_position(false);
if (valid_obs > 0 || glo_valid_obs > 0)
if ((valid_obs + glo_valid_obs) > 3)
{
int result = 0;
nav_t nav_data;
@ -495,5 +497,5 @@ bool rtklib_solver::get_PVT(const std::map<int, Gnss_Synchro>& gnss_observables_
}
}
}
return this->is_valid_position();
return is_valid_position();
}

View File

@ -33,6 +33,7 @@ set(ACQ_ADAPTER_SOURCES
galileo_e5a_noncoherent_iq_acquisition_caf.cc
galileo_e5a_pcps_acquisition.cc
glonass_l1_ca_pcps_acquisition.cc
glonass_l2_ca_pcps_acquisition.cc
)
if(ENABLE_FPGA)

View File

@ -45,6 +45,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{
pcpsconf_t acq_parameters;
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./data/acquisition.dat";
@ -55,32 +56,33 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_;
if_ = configuration_->property(role + ".if", 0);
acq_parameters.freq = if_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 4);
if (sampled_ms_ % 4 != 0)
{
sampled_ms_ = static_cast<int>(sampled_ms_ / 4) * 4;
LOG(WARNING) << "coherent_integration_time should be multiple of "
<< "Galileo code length (4 ms). coherent_integration_time = "
<< sampled_ms_ << " ms will be used.";
}
acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = 4;
acq_parameters.sampled_ms = sampled_ms_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_;
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false); //will be true in future versions
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false); //will be true in future versions
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code (4 ms) -----------------
code_length_ = round(fs_in_ / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS));
int samples_per_ms = round(code_length_ / 4.0);
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)));
acq_parameters.samples_per_code = code_length_;
int samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001));
acq_parameters.samples_per_ms = samples_per_ms;
vector_length_ = sampled_ms_ * samples_per_ms;
if (bit_transition_flag_)
@ -98,10 +100,11 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
{
item_size_ = sizeof(gr_complex);
}
acquisition_ = pcps_make_acquisition(sampled_ms_, max_dwells_,
doppler_max_, if_, fs_in_, samples_per_ms, code_length_,
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_,
dump_filename_, item_size_);
acq_parameters.it_size = item_size_;
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);

View File

@ -44,6 +44,7 @@ using google::LogMessage;
GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* configuration,
std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{
pcpsconf_t acq_parameters;
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "../data/acquisition.dat";
@ -54,6 +55,8 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_;
acq_parameters.freq = 0;
acq_pilot_ = configuration_->property(role + ".acquire_pilot", false);
acq_iq_ = configuration_->property(role + ".acquire_iq", false);
if (acq_iq_)
@ -61,17 +64,23 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
acq_pilot_ = false;
}
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = 1;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_;
use_CFAR_ = configuration_->property(role + ".use_CFAR_algorithm", false);
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_;
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_;
//--- Find number of samples per spreading code (1ms)-------------------------
code_length_ = round(static_cast<double>(fs_in_) / Galileo_E5a_CODE_CHIP_RATE_HZ * static_cast<double>(Galileo_E5a_CODE_LENGTH_CHIPS));
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / Galileo_E5a_CODE_CHIP_RATE_HZ * static_cast<double>(Galileo_E5a_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * sampled_ms_;
code_ = new gr_complex[vector_length_];
@ -89,10 +98,14 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
item_size_ = sizeof(gr_complex);
LOG(WARNING) << item_type_ << " unknown acquisition item type";
}
acquisition_ = pcps_make_acquisition(sampled_ms_, max_dwells_, doppler_max_, 0, fs_in_,
code_length_, code_length_, bit_transition_flag_, use_CFAR_, dump_, blocking_,
dump_filename_, item_size_);
acq_parameters.it_size = item_size_;
acq_parameters.samples_per_code = code_length_;
acq_parameters.samples_per_ms = code_length_;
acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
channel_ = 0;

View File

@ -34,8 +34,8 @@
#include "glonass_l1_ca_pcps_acquisition.h"
#include "configuration_interface.h"
#include "glonass_l1_signal_processing.h"
#include "GLONASS_L1_CA.h"
#include "gnss_sdr_flags.h"
#include "GLONASS_L1_L2_CA.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
@ -46,6 +46,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{
pcpsconf_t acq_parameters;
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./data/acquisition.dat";
@ -56,22 +57,28 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_;
if_ = configuration_->property(role + ".if", 0);
acq_parameters.freq = if_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_;
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code -------------------------
code_length_ = round(fs_in_ / (GLONASS_L1_CA_CODE_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS));
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (GLONASS_L1_CA_CODE_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * sampled_ms_;
@ -90,9 +97,14 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
{
item_size_ = sizeof(gr_complex);
}
acquisition_ = pcps_make_acquisition(sampled_ms_, max_dwells_,
doppler_max_, if_, fs_in_, code_length_, code_length_,
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_, dump_filename_, item_size_);
acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_ms = code_length_;
acq_parameters.samples_per_code = code_length_;
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);

View File

@ -0,0 +1,324 @@
/*!
* \file glonass_l2_ca_pcps_acquisition.cc
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Glonass L2 C/A signals
* \author Damian Miralles, 2018, dmiralles2009@gmail.com
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2017 (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 "glonass_l2_ca_pcps_acquisition.h"
#include "configuration_interface.h"
#include "glonass_l2_signal_processing.h"
#include "GLONASS_L1_L2_CA.h"
#include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
using google::LogMessage;
GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{
pcpsconf_t acq_parameters;
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./data/acquisition.dat";
DLOG(INFO) << "role " << role;
item_type_ = configuration_->property(role + ".item_type", default_item_type);
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_;
if_ = configuration_->property(role + ".if", 0);
acq_parameters.freq = if_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_;
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (GLONASS_L2_CA_CODE_RATE_HZ / GLONASS_L2_CA_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * sampled_ms_;
if (bit_transition_flag_)
{
vector_length_ *= 2;
}
code_ = new gr_complex[vector_length_];
if (item_type_.compare("cshort") == 0)
{
item_size_ = sizeof(lv_16sc_t);
}
else
{
item_size_ = sizeof(gr_complex);
}
acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_ms = code_length_;
acq_parameters.samples_per_code = code_length_;
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
if (item_type_.compare("cbyte") == 0)
{
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
float_to_complex_ = gr::blocks::float_to_complex::make();
}
channel_ = 0;
threshold_ = 0.0;
doppler_step_ = 0;
gnss_synchro_ = 0;
}
GlonassL2CaPcpsAcquisition::~GlonassL2CaPcpsAcquisition()
{
delete[] code_;
}
void GlonassL2CaPcpsAcquisition::set_channel(unsigned int channel)
{
channel_ = channel;
acquisition_->set_channel(channel_);
}
void GlonassL2CaPcpsAcquisition::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + ".pfa", 0.0);
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
acquisition_->set_threshold(threshold_);
}
void GlonassL2CaPcpsAcquisition::set_doppler_max(unsigned int doppler_max)
{
doppler_max_ = doppler_max;
acquisition_->set_doppler_max(doppler_max_);
}
void GlonassL2CaPcpsAcquisition::set_doppler_step(unsigned int doppler_step)
{
doppler_step_ = doppler_step;
acquisition_->set_doppler_step(doppler_step_);
}
void GlonassL2CaPcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
{
gnss_synchro_ = gnss_synchro;
acquisition_->set_gnss_synchro(gnss_synchro_);
}
signed int GlonassL2CaPcpsAcquisition::mag()
{
return acquisition_->mag();
}
void GlonassL2CaPcpsAcquisition::init()
{
acquisition_->init();
set_local_code();
}
void GlonassL2CaPcpsAcquisition::set_local_code()
{
std::complex<float>* code = new std::complex<float>[code_length_];
glonass_l2_ca_code_gen_complex_sampled(code, /* gnss_synchro_->PRN,*/ fs_in_, 0);
for (unsigned int i = 0; i < sampled_ms_; i++)
{
memcpy(&(code_[i * code_length_]), code,
sizeof(gr_complex) * code_length_);
}
acquisition_->set_local_code(code_);
delete[] code;
}
void GlonassL2CaPcpsAcquisition::reset()
{
acquisition_->set_active(true);
}
void GlonassL2CaPcpsAcquisition::set_state(int state)
{
acquisition_->set_state(state);
}
float GlonassL2CaPcpsAcquisition::calculate_threshold(float pfa)
{
//Calculate the threshold
unsigned int frequency_bins = 0;
/*
for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
{
frequency_bins++;
}
*/
frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_;
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
unsigned int ncells = vector_length_ * frequency_bins;
double exponent = 1 / static_cast<double>(ncells);
double val = pow(1.0 - pfa, exponent);
double lambda = static_cast<double>(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda);
float threshold = static_cast<float>(quantile(mydist, val));
return threshold;
}
void GlonassL2CaPcpsAcquisition::connect(gr::top_block_sptr top_block)
{
if (item_type_.compare("gr_complex") == 0)
{
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
}
else if (item_type_.compare("cshort") == 0)
{
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
}
else if (item_type_.compare("cbyte") == 0)
{
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
top_block->connect(float_to_complex_, 0, stream_to_vector_, 0);
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
}
else
{
LOG(WARNING) << item_type_ << " unknown acquisition item type";
}
}
void GlonassL2CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
{
if (item_type_.compare("gr_complex") == 0)
{
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
}
else if (item_type_.compare("cshort") == 0)
{
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
}
else if (item_type_.compare("cbyte") == 0)
{
// Since a byte-based acq implementation is not available,
// we just convert cshorts to gr_complex
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0);
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
}
else
{
LOG(WARNING) << item_type_ << " unknown acquisition item type";
}
}
gr::basic_block_sptr GlonassL2CaPcpsAcquisition::get_left_block()
{
if (item_type_.compare("gr_complex") == 0)
{
return stream_to_vector_;
}
else if (item_type_.compare("cshort") == 0)
{
return stream_to_vector_;
}
else if (item_type_.compare("cbyte") == 0)
{
return cbyte_to_float_x2_;
}
else
{
LOG(WARNING) << item_type_ << " unknown acquisition item type";
return nullptr;
}
}
gr::basic_block_sptr GlonassL2CaPcpsAcquisition::get_right_block()
{
return acquisition_;
}

View File

@ -0,0 +1,166 @@
/*!
* \file glonass_l2_ca_pcps_acquisition.h
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Glonass L2 C/A signals
* \author Damian Miralles, 2018, dmiralles2009@gmail.com
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2017 (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_GLONASS_L2_CA_PCPS_ACQUISITION_H_
#define GNSS_SDR_GLONASS_L2_CA_PCPS_ACQUISITION_H_
#include "acquisition_interface.h"
#include "gnss_synchro.h"
#include "pcps_acquisition.h"
#include "complex_byte_to_float_x2.h"
#include <gnuradio/blocks/stream_to_vector.h>
#include <gnuradio/blocks/float_to_complex.h>
#include <string>
class ConfigurationInterface;
/*!
* \brief This class adapts a PCPS acquisition block to an AcquisitionInterface
* for GLONASS L2 C/A signals
*/
class GlonassL2CaPcpsAcquisition : public AcquisitionInterface
{
public:
GlonassL2CaPcpsAcquisition(ConfigurationInterface* configuration,
std::string role, unsigned int in_streams,
unsigned int out_streams);
virtual ~GlonassL2CaPcpsAcquisition();
inline std::string role() override
{
return role_;
}
/*!
* \brief Returns "GLONASS_L2_CA_PCPS_Acquisition"
*/
inline std::string implementation() override
{
return "GLONASS_L2_CA_PCPS_Acquisition";
}
inline size_t item_size() override
{
return item_size_;
}
void connect(gr::top_block_sptr top_block) override;
void disconnect(gr::top_block_sptr top_block) override;
gr::basic_block_sptr get_left_block() override;
gr::basic_block_sptr get_right_block() override;
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
* to efficiently exchange synchronization data between acquisition and
* tracking blocks
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
/*!
* \brief Set acquisition channel unique ID
*/
void set_channel(unsigned int channel) override;
/*!
* \brief Set statistics threshold of PCPS algorithm
*/
void set_threshold(float threshold) override;
/*!
* \brief Set maximum Doppler off grid search
*/
void set_doppler_max(unsigned int doppler_max) override;
/*!
* \brief Set Doppler steps for the grid search
*/
void set_doppler_step(unsigned int doppler_step) override;
/*!
* \brief Initializes acquisition algorithm.
*/
void init() override;
/*!
* \brief Sets local code for GLONASS L2/CA PCPS acquisition algorithm.
*/
void set_local_code() override;
/*!
* \brief Returns the maximum peak of grid search
*/
signed int mag() override;
/*!
* \brief Restart acquisition algorithm
*/
void reset() override;
/*!
* \brief If state = 1, it forces the block to start acquiring from the first sample
*/
void set_state(int state);
private:
ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_;
gr::blocks::stream_to_vector::sptr stream_to_vector_;
gr::blocks::float_to_complex::sptr float_to_complex_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
size_t item_size_;
std::string item_type_;
unsigned int vector_length_;
unsigned int code_length_;
bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_;
unsigned int channel_;
float threshold_;
unsigned int doppler_max_;
unsigned int doppler_step_;
unsigned int sampled_ms_;
unsigned int max_dwells_;
long fs_in_;
long if_;
bool dump_;
bool blocking_;
std::string dump_filename_;
std::complex<float>* code_;
Gnss_Synchro* gnss_synchro_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
float calculate_threshold(float pfa);
};
#endif /* GNSS_SDR_GLONASS_L2_CA_PCPS_ACQUISITION_H_ */

View File

@ -48,6 +48,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{
pcpsconf_t acq_parameters;
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./data/acquisition.dat";
@ -57,22 +58,31 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
item_type_ = configuration_->property(role + ".item_type", default_item_type);
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_;
if_ = configuration_->property(role + ".if", 0);
acq_parameters.freq = if_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_;
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
//--- Find number of samples per spreading code -------------------------
code_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * sampled_ms_;
@ -91,9 +101,10 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
{
item_size_ = sizeof(gr_complex);
}
acquisition_ = pcps_make_acquisition(sampled_ms_, max_dwells_,
doppler_max_, if_, fs_in_, code_length_, code_length_,
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_, dump_filename_, item_size_);
acq_parameters.samples_per_ms = code_length_;
acq_parameters.samples_per_code = code_length_;
acq_parameters.it_size = item_size_;
acquisition_ = pcps_make_acquisition(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);

View File

@ -46,6 +46,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{
pcpsconf_t acq_parameters;
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./data/acquisition.dat";
@ -57,21 +58,26 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_;
if_ = configuration_->property(role + ".if", 0);
acq_parameters.freq = if_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_;
doppler_max_ = configuration->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_;
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code -------------------------
code_length_ = round(static_cast<double>(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / static_cast<double>(GPS_L2_M_CODE_LENGTH_CHIPS)));
code_length_ = std::round(static_cast<double>(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / static_cast<double>(GPS_L2_M_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_;
@ -90,10 +96,14 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
{
item_size_ = sizeof(gr_complex);
}
acquisition_ = pcps_make_acquisition(1, max_dwells_,
doppler_max_, if_, fs_in_, code_length_, code_length_,
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_,
dump_filename_, item_size_);
acq_parameters.samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001));
acq_parameters.samples_per_code = code_length_;
acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = 20;
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", true);
acquisition_ = pcps_make_acquisition(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);

View File

@ -46,6 +46,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{
pcpsconf_t acq_parameters;
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./data/acquisition.dat";
@ -56,21 +57,26 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_;
if_ = configuration_->property(role + ".if", 0);
acq_parameters.freq = if_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_;
doppler_max_ = configuration->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_;
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code -------------------------
code_length_ = round(static_cast<double>(fs_in_) / (GPS_L5i_CODE_RATE_HZ / static_cast<double>(GPS_L5i_CODE_LENGTH_CHIPS)));
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (GPS_L5i_CODE_RATE_HZ / static_cast<double>(GPS_L5i_CODE_LENGTH_CHIPS))));
vector_length_ = code_length_;
@ -89,10 +95,14 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
{
item_size_ = sizeof(gr_complex);
}
acquisition_ = pcps_make_acquisition(1, max_dwells_,
doppler_max_, if_, fs_in_, code_length_, code_length_,
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_,
dump_filename_, item_size_);
acq_parameters.samples_per_code = code_length_;
acq_parameters.samples_per_ms = code_length_;
acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = 1;
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);

View File

@ -34,8 +34,8 @@
*/
#include "pcps_acquisition.h"
#include "GPS_L1_CA.h" // for GPS_TWO_PI
#include "GLONASS_L1_CA.h" // for GLONASS_TWO_PI
#include "GPS_L1_CA.h" // for GPS_TWO_PI
#include "GLONASS_L1_L2_CA.h" // for GLONASS_TWO_PI"
#include <glog/logging.h>
#include <gnuradio/io_signature.h>
#include <matio.h>
@ -45,57 +45,34 @@
using google::LogMessage;
pcps_acquisition_sptr pcps_make_acquisition(
unsigned int sampled_ms, unsigned int max_dwells,
unsigned int doppler_max, long freq, long fs_in,
int samples_per_ms, int samples_per_code,
bool bit_transition_flag, bool use_CFAR_algorithm_flag,
bool dump, bool blocking,
std::string dump_filename, size_t it_size)
pcps_acquisition_sptr pcps_make_acquisition(pcpsconf_t conf_)
{
return pcps_acquisition_sptr(
new pcps_acquisition(sampled_ms, max_dwells, doppler_max, freq, fs_in, samples_per_ms,
samples_per_code, bit_transition_flag, use_CFAR_algorithm_flag, dump, blocking, dump_filename, it_size));
return pcps_acquisition_sptr(new pcps_acquisition(conf_));
}
pcps_acquisition::pcps_acquisition(
unsigned int sampled_ms, unsigned int max_dwells,
unsigned int doppler_max, long freq, long fs_in,
int samples_per_ms, int samples_per_code,
bool bit_transition_flag, bool use_CFAR_algorithm_flag,
bool dump, bool blocking,
std::string dump_filename,
size_t it_size) : gr::block("pcps_acquisition",
gr::io_signature::make(1, 1, it_size * sampled_ms * samples_per_ms * (bit_transition_flag ? 2 : 1)),
gr::io_signature::make(0, 0, it_size * sampled_ms * samples_per_ms * (bit_transition_flag ? 2 : 1)))
pcps_acquisition::pcps_acquisition(pcpsconf_t conf_) : gr::block("pcps_acquisition",
gr::io_signature::make(1, 1, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1)),
gr::io_signature::make(0, 0, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1)))
{
this->message_port_register_out(pmt::mp("events"));
acq_parameters = conf_;
d_sample_counter = 0; // SAMPLE COUNTER
d_active = false;
d_state = 0;
d_freq = freq;
d_old_freq = freq;
d_fs_in = fs_in;
d_samples_per_ms = samples_per_ms;
d_samples_per_code = samples_per_code;
d_sampled_ms = sampled_ms;
d_max_dwells = max_dwells;
d_old_freq = conf_.freq;
d_well_count = 0;
d_doppler_max = doppler_max;
d_fft_size = d_sampled_ms * d_samples_per_ms;
d_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms;
d_mag = 0;
d_input_power = 0.0;
d_num_doppler_bins = 0;
d_bit_transition_flag = bit_transition_flag;
d_use_CFAR_algorithm_flag = use_CFAR_algorithm_flag;
d_threshold = 0.0;
d_doppler_step = 0;
d_code_phase = 0;
d_doppler_center_step_two = 0.0;
d_test_statistics = 0.0;
d_channel = 0;
if (it_size == sizeof(gr_complex))
if (conf_.it_size == sizeof(gr_complex))
{
d_cshort = false;
}
@ -114,10 +91,10 @@ pcps_acquisition::pcps_acquisition(
//
// We can avoid this by doing linear correlation, effectively doubling the
// size of the input buffer and padding the code with zeros.
if (d_bit_transition_flag)
if (acq_parameters.bit_transition_flag)
{
d_fft_size *= 2;
d_max_dwells = 1; //Activation of d_bit_transition_flag invalidates the value of d_max_dwells
acq_parameters.max_dwells = 1; //Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells
}
d_fft_codes = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
@ -129,12 +106,9 @@ pcps_acquisition::pcps_acquisition(
// Inverse FFT
d_ifft = new gr::fft::fft_complex(d_fft_size, false);
// For dumping samples into a file
d_dump = dump;
d_dump_filename = dump_filename;
d_gnss_synchro = 0;
d_grid_doppler_wipeoffs = 0;
d_blocking = blocking;
d_grid_doppler_wipeoffs = nullptr;
d_grid_doppler_wipeoffs_step_two = nullptr;
d_worker_active = false;
d_data_buffer = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
if (d_cshort)
@ -146,6 +120,7 @@ pcps_acquisition::pcps_acquisition(
d_data_buffer_sc = nullptr;
}
grid_ = arma::fmat();
d_step_two = false;
}
@ -159,6 +134,14 @@ pcps_acquisition::~pcps_acquisition()
}
delete[] d_grid_doppler_wipeoffs;
}
if (acq_parameters.make_2_steps)
{
for (unsigned int i = 0; i < acq_parameters.num_doppler_bins_step2; i++)
{
volk_gnsssdr_free(d_grid_doppler_wipeoffs_step_two[i]);
}
delete[] d_grid_doppler_wipeoffs_step_two;
}
volk_gnsssdr_free(d_fft_codes);
volk_gnsssdr_free(d_magnitude);
delete d_ifft;
@ -174,7 +157,7 @@ pcps_acquisition::~pcps_acquisition()
void pcps_acquisition::set_local_code(std::complex<float>* code)
{
// reset the intermediate frequency
d_freq = d_old_freq;
acq_parameters.freq = d_old_freq;
// This will check if it's fdma, if yes will update the intermediate frequency and the doppler grid
if (is_fdma())
{
@ -185,7 +168,7 @@ void pcps_acquisition::set_local_code(std::complex<float>* code)
// [ 0 0 0 ... 0 c_0 c_1 ... c_L]
// where c_i is the local code and there are L zeros and L chips
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
if (d_bit_transition_flag)
if (acq_parameters.bit_transition_flag)
{
int offset = d_fft_size / 2;
std::fill_n(d_fft_if->get_inbuf(), offset, gr_complex(0.0, 0.0));
@ -206,8 +189,14 @@ bool pcps_acquisition::is_fdma()
// Dealing with FDMA system
if (strcmp(d_gnss_synchro->Signal, "1G") == 0)
{
d_freq += DFRQ1_GLO * GLONASS_PRN.at(d_gnss_synchro->PRN);
LOG(INFO) << "Trying to acquire SV PRN " << d_gnss_synchro->PRN << " with freq " << d_freq << " in Glonass Channel " << GLONASS_PRN.at(d_gnss_synchro->PRN) << std::endl;
acq_parameters.freq += DFRQ1_GLO * GLONASS_PRN.at(d_gnss_synchro->PRN);
LOG(INFO) << "Trying to acquire SV PRN " << d_gnss_synchro->PRN << " with freq " << acq_parameters.freq << " in Glonass Channel " << GLONASS_PRN.at(d_gnss_synchro->PRN) << std::endl;
return true;
}
else if (strcmp(d_gnss_synchro->Signal, "2G") == 0)
{
acq_parameters.freq += DFRQ2_GLO * GLONASS_PRN.at(d_gnss_synchro->PRN);
LOG(INFO) << "Trying to acquire SV PRN " << d_gnss_synchro->PRN << " with freq " << acq_parameters.freq << " in Glonass Channel " << GLONASS_PRN.at(d_gnss_synchro->PRN) << std::endl;
return true;
}
else
@ -219,7 +208,7 @@ bool pcps_acquisition::is_fdma()
void pcps_acquisition::update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq)
{
float phase_step_rad = GPS_TWO_PI * freq / static_cast<float>(d_fs_in);
float phase_step_rad = GPS_TWO_PI * freq / static_cast<float>(acq_parameters.fs_in);
float _phase[1];
_phase[0] = 0;
volk_gnsssdr_s32f_sincos_32fc(carrier_vector, -phase_step_rad, _phase, correlator_length_samples);
@ -239,22 +228,29 @@ void pcps_acquisition::init()
d_mag = 0.0;
d_input_power = 0.0;
d_num_doppler_bins = static_cast<unsigned int>(std::ceil(static_cast<double>(static_cast<int>(d_doppler_max) - static_cast<int>(-d_doppler_max)) / static_cast<double>(d_doppler_step)));
d_num_doppler_bins = static_cast<unsigned int>(std::ceil(static_cast<double>(static_cast<int>(acq_parameters.doppler_max) - static_cast<int>(-acq_parameters.doppler_max)) / static_cast<double>(d_doppler_step)));
// Create the carrier Doppler wipeoff signals
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
if (acq_parameters.make_2_steps)
{
d_grid_doppler_wipeoffs_step_two = new gr_complex*[acq_parameters.num_doppler_bins_step2];
for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++)
{
d_grid_doppler_wipeoffs_step_two[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
}
}
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
{
d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index;
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_freq + doppler);
int doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, acq_parameters.freq + doppler);
}
d_worker_active = false;
if (d_dump)
if (acq_parameters.dump)
{
unsigned int effective_fft_size = (d_bit_transition_flag ? (d_fft_size / 2) : d_fft_size);
unsigned int effective_fft_size = (acq_parameters.bit_transition_flag ? (d_fft_size / 2) : d_fft_size);
grid_ = arma::fmat(effective_fft_size, d_num_doppler_bins, arma::fill::zeros);
}
}
@ -264,12 +260,19 @@ void pcps_acquisition::update_grid_doppler_wipeoffs()
{
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
{
d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index;
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_freq + doppler);
int doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, acq_parameters.freq + doppler);
}
}
void pcps_acquisition::update_grid_doppler_wipeoffs_step2()
{
for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++)
{
float doppler = (static_cast<float>(doppler_index) - static_cast<float>(acq_parameters.num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2;
update_local_carrier(d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size, d_doppler_center_step_two + doppler);
}
}
void pcps_acquisition::set_state(int state)
{
@ -348,10 +351,17 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
*/
gr::thread::scoped_lock lk(d_setlock);
if (!d_active || d_worker_active)
if (!d_active or d_worker_active)
{
d_sample_counter += d_fft_size * ninput_items[0];
consume_each(ninput_items[0]);
if (d_step_two)
{
d_doppler_center_step_two = static_cast<float>(d_gnss_synchro->Acq_doppler_hz);
update_grid_doppler_wipeoffs_step2();
d_state = 0;
d_active = true;
}
return 0;
}
@ -384,7 +394,7 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
{
memcpy(d_data_buffer, input_items[0], d_fft_size * sizeof(gr_complex));
}
if (d_blocking)
if (acq_parameters.blocking)
{
lk.unlock();
acquisition_core(d_sample_counter);
@ -408,11 +418,10 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
gr::thread::scoped_lock lk(d_setlock);
// initialize acquisition algorithm
int doppler;
uint32_t indext = 0;
float magt = 0.0;
const gr_complex* in = d_data_buffer; //Get the input samples pointer
int effective_fft_size = (d_bit_transition_flag ? d_fft_size / 2 : d_fft_size);
int effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size);
if (d_cshort)
{
volk_gnsssdr_16ic_convert_32fc(d_data_buffer, d_data_buffer_sc, d_fft_size);
@ -426,12 +435,12 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
DLOG(INFO) << "Channel: " << d_channel
<< " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
<< " ,sample stamp: " << samp_count << ", threshold: "
<< d_threshold << ", doppler_max: " << d_doppler_max
<< d_threshold << ", doppler_max: " << acq_parameters.doppler_max
<< ", doppler_step: " << d_doppler_step
<< ", use_CFAR_algorithm_flag: " << (d_use_CFAR_algorithm_flag ? "true" : "false");
<< ", use_CFAR_algorithm_flag: " << (acq_parameters.use_CFAR_algorithm_flag ? "true" : "false");
lk.unlock();
if (d_use_CFAR_algorithm_flag)
if (acq_parameters.use_CFAR_algorithm_flag)
{
// 1- (optional) Compute the input signal power estimation
volk_32fc_magnitude_squared_32f(d_magnitude, in, d_fft_size);
@ -439,142 +448,241 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
d_input_power /= static_cast<float>(d_fft_size);
}
// 2- Doppler frequency search loop
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
if (!d_step_two)
{
// doppler search steps
doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index;
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
// 3- Perform the FFT-based convolution (parallel time search)
// Compute the FFT of the carrier wiped--off incoming signal
d_fft_if->execute();
// Multiply carrier wiped--off, Fourier transformed incoming signal
// with the local FFT'd code reference using SIMD operations with VOLK library
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes, d_fft_size);
// compute the inverse FFT
d_ifft->execute();
// Search maximum
size_t offset = (d_bit_transition_flag ? effective_fft_size : 0);
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size);
volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size);
magt = d_magnitude[indext];
if (d_use_CFAR_algorithm_flag)
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
{
// Normalize the maximum value to correct the scale factor introduced by FFTW
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
}
// 4- record the maximum peak and the associated synchronization parameters
if (d_mag < magt)
{
d_mag = magt;
// doppler search steps
int doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
if (!d_use_CFAR_algorithm_flag)
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
// 3- Perform the FFT-based convolution (parallel time search)
// Compute the FFT of the carrier wiped--off incoming signal
d_fft_if->execute();
// Multiply carrier wiped--off, Fourier transformed incoming signal
// with the local FFT'd code reference using SIMD operations with VOLK library
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes, d_fft_size);
// compute the inverse FFT
d_ifft->execute();
// Search maximum
size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0);
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size);
volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size);
magt = d_magnitude[indext];
if (acq_parameters.use_CFAR_algorithm_flag)
{
// Search grid noise floor approximation for this doppler line
volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size);
d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1);
// Normalize the maximum value to correct the scale factor introduced by FFTW
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
}
// In case that d_bit_transition_flag = true, we compare the potentially
// new maximum test statistics (d_mag/d_input_power) with the value in
// d_test_statistics. When the second dwell is being processed, the value
// of d_mag/d_input_power could be lower than d_test_statistics (i.e,
// the maximum test statistics in the previous dwell is greater than
// current d_mag/d_input_power). Note that d_test_statistics is not
// restarted between consecutive dwells in multidwell operation.
if (d_test_statistics < (d_mag / d_input_power) || !d_bit_transition_flag)
// 4- record the maximum peak and the associated synchronization parameters
if (d_mag < magt)
{
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
d_mag = magt;
// 5- Compute the test statistics and compare to the threshold
//d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;
d_test_statistics = d_mag / d_input_power;
}
}
// Record results to file if required
if (d_dump)
{
memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size);
if (doppler_index == (d_num_doppler_bins - 1))
{
std::string filename = d_dump_filename;
filename.append("_");
filename.append(1, d_gnss_synchro->System);
filename.append("_");
filename.append(1, d_gnss_synchro->Signal[0]);
filename.append(1, d_gnss_synchro->Signal[1]);
filename.append("_sat_");
filename.append(std::to_string(d_gnss_synchro->PRN));
filename.append(".mat");
mat_t* matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73);
if (matfp == NULL)
if (!acq_parameters.use_CFAR_algorithm_flag)
{
std::cout << "Unable to create or open Acquisition dump file" << std::endl;
d_dump = false;
// Search grid noise floor approximation for this doppler line
volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size);
d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1);
}
else
// In case that acq_parameters.bit_transition_flag = true, we compare the potentially
// new maximum test statistics (d_mag/d_input_power) with the value in
// d_test_statistics. When the second dwell is being processed, the value
// of d_mag/d_input_power could be lower than d_test_statistics (i.e,
// the maximum test statistics in the previous dwell is greater than
// current d_mag/d_input_power). Note that d_test_statistics is not
// restarted between consecutive dwells in multidwell operation.
if (d_test_statistics < (d_mag / d_input_power) or !acq_parameters.bit_transition_flag)
{
size_t dims[2] = {static_cast<size_t>(effective_fft_size), static_cast<size_t>(d_num_doppler_bins)};
matvar_t* matvar = Mat_VarCreate("grid", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, grid_.memptr(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code);
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
dims[0] = static_cast<size_t>(1);
dims[1] = static_cast<size_t>(1);
matvar = Mat_VarCreate("doppler_max", MAT_C_SINGLE, MAT_T_UINT32, 1, dims, &d_doppler_max, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
// 5- Compute the test statistics and compare to the threshold
//d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;
d_test_statistics = d_mag / d_input_power;
}
}
// Record results to file if required
if (acq_parameters.dump)
{
memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size);
if (doppler_index == (d_num_doppler_bins - 1))
{
std::string filename = acq_parameters.dump_filename;
filename.append("_");
filename.append(1, d_gnss_synchro->System);
filename.append("_");
filename.append(1, d_gnss_synchro->Signal[0]);
filename.append(1, d_gnss_synchro->Signal[1]);
filename.append("_sat_");
filename.append(std::to_string(d_gnss_synchro->PRN));
filename.append(".mat");
mat_t* matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73);
if (matfp == NULL)
{
std::cout << "Unable to create or open Acquisition dump file" << std::endl;
acq_parameters.dump = false;
}
else
{
size_t dims[2] = {static_cast<size_t>(effective_fft_size), static_cast<size_t>(d_num_doppler_bins)};
matvar_t* matvar = Mat_VarCreate("grid", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, grid_.memptr(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("doppler_step", MAT_C_SINGLE, MAT_T_UINT32, 1, dims, &d_doppler_step, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
dims[0] = static_cast<size_t>(1);
dims[1] = static_cast<size_t>(1);
matvar = Mat_VarCreate("doppler_max", MAT_C_SINGLE, MAT_T_UINT32, 1, dims, &acq_parameters.doppler_max, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
Mat_Close(matfp);
matvar = Mat_VarCreate("doppler_step", MAT_C_SINGLE, MAT_T_UINT32, 1, dims, &d_doppler_step, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
Mat_Close(matfp);
}
}
}
}
}
else
{
for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++)
{
// doppler search steps
float doppler = d_doppler_center_step_two + (static_cast<float>(doppler_index) - static_cast<float>(acq_parameters.num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2;
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size);
// 3- Perform the FFT-based convolution (parallel time search)
// Compute the FFT of the carrier wiped--off incoming signal
d_fft_if->execute();
// Multiply carrier wiped--off, Fourier transformed incoming signal
// with the local FFT'd code reference using SIMD operations with VOLK library
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes, d_fft_size);
// compute the inverse FFT
d_ifft->execute();
// Search maximum
size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0);
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size);
volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size);
magt = d_magnitude[indext];
if (acq_parameters.use_CFAR_algorithm_flag)
{
// Normalize the maximum value to correct the scale factor introduced by FFTW
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
}
// 4- record the maximum peak and the associated synchronization parameters
if (d_mag < magt)
{
d_mag = magt;
if (!acq_parameters.use_CFAR_algorithm_flag)
{
// Search grid noise floor approximation for this doppler line
volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size);
d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1);
}
// In case that acq_parameters.bit_transition_flag = true, we compare the potentially
// new maximum test statistics (d_mag/d_input_power) with the value in
// d_test_statistics. When the second dwell is being processed, the value
// of d_mag/d_input_power could be lower than d_test_statistics (i.e,
// the maximum test statistics in the previous dwell is greater than
// current d_mag/d_input_power). Note that d_test_statistics is not
// restarted between consecutive dwells in multidwell operation.
if (d_test_statistics < (d_mag / d_input_power) or !acq_parameters.bit_transition_flag)
{
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code);
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
// 5- Compute the test statistics and compare to the threshold
//d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;
d_test_statistics = d_mag / d_input_power;
}
}
}
}
lk.lock();
if (!d_bit_transition_flag)
if (!acq_parameters.bit_transition_flag)
{
if (d_test_statistics > d_threshold)
{
d_state = 0; // Positive acquisition
d_active = false;
send_positive_acquisition();
if (acq_parameters.make_2_steps)
{
if (d_step_two)
{
send_positive_acquisition();
d_step_two = false;
d_state = 0; // Positive acquisition
}
else
{
d_step_two = true; // Clear input buffer and make small grid acquisition
d_state = 0;
}
}
else
{
send_positive_acquisition();
d_state = 0; // Positive acquisition
}
}
else if (d_well_count == d_max_dwells)
else if (d_well_count == acq_parameters.max_dwells)
{
d_state = 0;
d_active = false;
d_step_two = false;
send_negative_acquisition();
}
}
else
{
if (d_well_count == d_max_dwells) // d_max_dwells = 2
d_active = false;
if (d_test_statistics > d_threshold)
{
if (d_test_statistics > d_threshold)
if (acq_parameters.make_2_steps)
{
d_state = 0; // Positive acquisition
d_active = false;
send_positive_acquisition();
if (d_step_two)
{
send_positive_acquisition();
d_step_two = false;
d_state = 0; // Positive acquisition
}
else
{
d_step_two = true; // Clear input buffer and make small grid acquisition
d_state = 0;
}
}
else
{
d_state = 0; // Negative acquisition
d_active = false;
send_negative_acquisition();
send_positive_acquisition();
d_state = 0; // Positive acquisition
}
}
else
{
d_state = 0; // Negative acquisition
d_step_two = false;
send_negative_acquisition();
}
}
d_worker_active = false;
}

View File

@ -59,18 +59,33 @@
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <string>
typedef struct
{
/* pcps acquisition configuration */
unsigned int sampled_ms;
unsigned int max_dwells;
unsigned int doppler_max;
unsigned int num_doppler_bins_step2;
float doppler_step2;
long freq;
long fs_in;
int samples_per_ms;
int samples_per_code;
bool bit_transition_flag;
bool use_CFAR_algorithm_flag;
bool dump;
bool blocking;
bool make_2_steps;
std::string dump_filename;
size_t it_size;
} pcpsconf_t;
class pcps_acquisition;
typedef boost::shared_ptr<pcps_acquisition> pcps_acquisition_sptr;
pcps_acquisition_sptr
pcps_make_acquisition(unsigned int sampled_ms, unsigned int max_dwells,
unsigned int doppler_max, long freq, long fs_in,
int samples_per_ms, int samples_per_code,
bool bit_transition_flag, bool use_CFAR_algorithm_flag,
bool dump, bool blocking,
std::string dump_filename, size_t it_size);
pcps_make_acquisition(pcpsconf_t conf_);
/*!
* \brief This class implements a Parallel Code Phase Search Acquisition.
@ -82,22 +97,13 @@ class pcps_acquisition : public gr::block
{
private:
friend pcps_acquisition_sptr
pcps_make_acquisition(unsigned int sampled_ms, unsigned int max_dwells,
unsigned int doppler_max, long freq, long fs_in,
int samples_per_ms, int samples_per_code,
bool bit_transition_flag, bool use_CFAR_algorithm_flag,
bool dump, bool blocking,
std::string dump_filename, size_t it_size);
pcps_make_acquisition(pcpsconf_t conf_);
pcps_acquisition(unsigned int sampled_ms, unsigned int max_dwells,
unsigned int doppler_max, long freq, long fs_in,
int samples_per_ms, int samples_per_code,
bool bit_transition_flag, bool use_CFAR_algorithm_flag,
bool dump, bool blocking,
std::string dump_filename, size_t it_size);
pcps_acquisition(pcpsconf_t conf_);
void update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq);
void update_grid_doppler_wipeoffs();
void update_grid_doppler_wipeoffs_step2();
bool is_fdma();
void acquisition_core(unsigned long int samp_count);
@ -106,42 +112,33 @@ private:
void send_positive_acquisition();
bool d_bit_transition_flag;
bool d_use_CFAR_algorithm_flag;
pcpsconf_t acq_parameters;
bool d_active;
bool d_dump;
bool d_worker_active;
bool d_blocking;
bool d_cshort;
bool d_step_two;
float d_threshold;
float d_mag;
float d_input_power;
float d_test_statistics;
float* d_magnitude;
long d_fs_in;
long d_freq;
long d_old_freq;
int d_samples_per_ms;
int d_samples_per_code;
int d_state;
unsigned int d_channel;
unsigned int d_doppler_max;
unsigned int d_doppler_step;
unsigned int d_sampled_ms;
unsigned int d_max_dwells;
float d_doppler_center_step_two;
unsigned int d_well_count;
unsigned int d_fft_size;
unsigned int d_num_doppler_bins;
unsigned int d_code_phase;
unsigned long int d_sample_counter;
gr_complex** d_grid_doppler_wipeoffs;
gr_complex** d_grid_doppler_wipeoffs_step_two;
gr_complex* d_fft_codes;
gr_complex* d_data_buffer;
lv_16sc_t* d_data_buffer_sc;
gr::fft::fft_complex* d_fft_if;
gr::fft::fft_complex* d_ifft;
Gnss_Synchro* d_gnss_synchro;
std::string d_dump_filename;
arma::fmat grid_;
public:
@ -223,7 +220,7 @@ public:
inline void set_doppler_max(unsigned int doppler_max)
{
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
d_doppler_max = doppler_max;
acq_parameters.doppler_max = doppler_max;
}
/*!

View File

@ -316,7 +316,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
gr_complex* corr_output = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_samples_per_code * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
/*Stores a copy of the folded version of the signal.This is used for
the FFT operations in future steps of excecution*/
the FFT operations in future steps of execution*/
// gr_complex in_folded[d_fft_size];
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
@ -468,7 +468,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
if (d_dump)
{
/*Since QuickSYnc performs a folded correlation in frequency by means
of the FFT, it is esential to also keep the values obtained from the
of the FFT, it is essential to also keep the values obtained from the
possible delay to show how it is maximize*/
std::stringstream filename;
std::streamsize n = sizeof(float) * (d_fft_size); // complex file write

View File

@ -16,40 +16,11 @@
# along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
#
#if(ENABLE_CUDA)
# # Append current NVCC flags by something, eg comput capability
# # set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} --gpu-architecture sm_30)
# list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_30,code=sm_30; -std=c++11;-O3; -use_fast_math -default-stream per-thread")
# set(CUDA_PROPAGATE_HOST_FLAGS OFF)
# CUDA_INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR})
# set(LIB_TYPE STATIC) #set the lib type
# CUDA_ADD_LIBRARY(CUDA_CORRELATOR_LIB ${LIB_TYPE} cuda_multicorrelator.h cuda_multicorrelator.cu)
# set(OPT_TRACKING_LIBRARIES ${OPT_TRACKING_LIBRARIES} CUDA_CORRELATOR_LIB)
# set(OPT_TRACKING_INCLUDES ${OPT_TRACKING_INCLUDES} ${CUDA_INCLUDE_DIRS} )
#endif(ENABLE_CUDA)
#set(TRACKING_LIB_SOURCES
set(ACQUISITION_LIB_SOURCES
gps_fpga_acquisition_8sc.cc
# cpu_multicorrelator.cc
# cpu_multicorrelator_16sc.cc
# lock_detectors.cc
# tcp_communication.cc
# tcp_packet_data.cc
# tracking_2nd_DLL_filter.cc
# tracking_2nd_PLL_filter.cc
# tracking_discriminators.cc
# tracking_FLL_PLL_filter.cc
# tracking_loop_filter.cc
)
#if(ENABLE_FPGA)
# SET(ACQUISITION_LIB_SOURCES ${ACQUISITION_LIB_SOURCES} fpga_acquisition_8sc.cc)
#endif(ENABLE_FPGA)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -59,34 +30,17 @@ include_directories(
${VOLK_INCLUDE_DIRS}
${GLOG_INCLUDE_DIRS}
${GFlags_INCLUDE_DIRS}
${OPT_TRACKING_INCLUDES}
${VOLK_GNSSSDR_INCLUDE_DIRS}
)
if(ENABLE_GENERIC_ARCH)
add_definitions( -DGENERIC_ARCH=1 )
endif(ENABLE_GENERIC_ARCH)
if (SSE3_AVAILABLE)
add_definitions( -DHAVE_SSE3=1 )
endif(SSE3_AVAILABLE)
#file(GLOB TRACKING_LIB_HEADERS "*.h")
file(GLOB ACQUISITION_LIB_HEADERS "*.h")
#list(SORT TRACKING_LIB_HEADERS)
list(SORT ACQUISITION_LIB_HEADERS)
#add_library(tracking_lib ${TRACKING_LIB_SOURCES} ${TRACKING_LIB_HEADERS})
add_library(acquisition_lib ${ACQUISITION_LIB_SOURCES} ${ACQUISITION_LIB_HEADERS})
#source_group(Headers FILES ${TRACKING_LIB_HEADERS})
source_group(Headers FILES ${ACQUISITION_LIB_HEADERS})
#target_link_libraries(tracking_lib ${OPT_TRACKING_LIBRARIES} ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES})
target_link_libraries(acquisition_lib ${OPT_ACQUISITION_LIBRARIES} ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES})
target_link_libraries(acquisition_lib ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES})
if(VOLK_GNSSSDR_FOUND)
# add_dependencies(tracking_lib glog-${glog_RELEASE})
add_dependencies(acquisition_lib glog-${glog_RELEASE})
else(VOLK_GNSSSDR_FOUND)
# add_dependencies(tracking_lib glog-${glog_RELEASE} volk_gnsssdr_module)
add_dependencies(acquisition_lib glog-${glog_RELEASE} volk_gnsssdr_module)
endif()

View File

@ -1,6 +1,6 @@
/*!
* \file notch_filter_lite.h
* \brief Adapts a ligth version of a multistate notch filter
* \brief Adapts a light version of a multistate notch filter
* \author Antonio Ramos, 2017. antonio.ramosdet(at)gmail.com
*
* Detailed description of the file here if needed.

View File

@ -1,6 +1,6 @@
/*!
* \file notch_lite_cc.h
* \brief Implements a notch filter ligth algorithm
* \brief Implements a notch filter light algorithm
* \author Antonio Ramos (antonio.ramosdet(at)gmail.com)
*
* -------------------------------------------------------------------------
@ -43,7 +43,7 @@ typedef boost::shared_ptr<NotchLite> notch_lite_sptr;
notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff);
/*!
* \brief This class implements a real-time software-defined multi state notch filter ligth version
* \brief This class implements a real-time software-defined multi state notch filter light version
*/
class NotchLite : public gr::block

View File

@ -27,6 +27,7 @@ set(GNSS_SPLIBS_SOURCES
gnss_signal_processing.cc
gps_sdr_signal_processing.cc
glonass_l1_signal_processing.cc
glonass_l2_signal_processing.cc
pass_through.cc
galileo_e5_signal_processing.cc
complex_byte_to_float_x2.cc

View File

@ -53,7 +53,7 @@ void galileo_e1_code_gen_int(int* _dest, char _Signal[3], signed int _prn)
for (size_t i = 0; i < Galileo_E1_B_PRIMARY_CODE[prn].length(); i++)
{
hex_to_binary_converter(&_dest[index], Galileo_E1_B_PRIMARY_CODE[prn].at(i));
index = index + 4;
index += 4;
}
}
else if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2)
@ -61,13 +61,9 @@ void galileo_e1_code_gen_int(int* _dest, char _Signal[3], signed int _prn)
for (size_t i = 0; i < Galileo_E1_C_PRIMARY_CODE[prn].length(); i++)
{
hex_to_binary_converter(&_dest[index], Galileo_E1_C_PRIMARY_CODE[prn].at(i));
index = index + 4;
index += 4;
}
}
else
{
return;
}
}
@ -107,6 +103,18 @@ void galileo_e1_sinboc_61_gen_int(int* _dest, int* _prn, unsigned int _length_ou
}
}
void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], unsigned int _prn)
{
std::string _galileo_signal = _Signal;
unsigned int _codeLength = static_cast<unsigned int>(Galileo_E1_B_CODE_LENGTH_CHIPS);
int primary_code_E1_chips[4092]; // _codeLength not accepted by Clang
galileo_e1_code_gen_int(primary_code_E1_chips, _Signal, _prn); //generate Galileo E1 code, 1 sample per chip
for (unsigned int i = 0; i < _codeLength; i++)
{
_dest[2 * i] = static_cast<float>(primary_code_E1_chips[i]);
_dest[2 * i + 1] = -_dest[2 * i];
}
}
void galileo_e1_gen_float(float* _dest, int* _prn, char _Signal[3])
{
@ -137,8 +145,6 @@ void galileo_e1_gen_float(float* _dest, int* _prn, char _Signal[3])
beta * static_cast<float>(sinboc_61[i]);
}
}
else
return;
}

View File

@ -34,6 +34,11 @@
#include <complex>
/*!
* \brief This function generates Galileo E1 code (can select E1B or E1C sinboc).
*
*/
void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], unsigned int _prn);
/*!
* \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc

View File

@ -0,0 +1,152 @@
/*!
* \file glonass_l2_signal_processing.cc
* \brief This class implements various functions for GLONASS L2 CA signals
* \author Damian Miralles, 2018, dmiralles2009(at)gmail.com
*
* Detailed description of the file here if needed.
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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 "glonass_l2_signal_processing.h"
auto auxCeil = [](float x) { return static_cast<int>(static_cast<long>((x) + 1)); };
void glonass_l2_ca_code_gen_complex(std::complex<float>* _dest, /* signed int _prn,*/ unsigned int _chip_shift)
{
const unsigned int _code_length = 511;
bool G1[_code_length];
bool G1_register[9];
bool feedback1;
bool aux;
unsigned int delay;
unsigned int lcv, lcv2;
for (lcv = 0; lcv < 9; lcv++)
{
G1_register[lcv] = 1;
}
/* Generate G1 Register */
for (lcv = 0; lcv < _code_length; lcv++)
{
G1[lcv] = G1_register[2];
feedback1 = G1_register[4] ^ G1_register[0];
for (lcv2 = 0; lcv2 < 8; lcv2++)
{
G1_register[lcv2] = G1_register[lcv2 + 1];
}
G1_register[8] = feedback1;
}
/* Generate PRN from G1 Register */
for (lcv = 0; lcv < _code_length; lcv++)
{
aux = G1[lcv];
if (aux == true)
{
_dest[lcv] = std::complex<float>(1, 0);
}
else
{
_dest[lcv] = std::complex<float>(-1, 0);
}
}
/* Set the delay */
delay = _code_length;
delay += _chip_shift;
delay %= _code_length;
/* Generate PRN from G1 and G2 Registers */
for (lcv = 0; lcv < _code_length; lcv++)
{
aux = G1[(lcv + _chip_shift) % _code_length];
if (aux == true)
{
_dest[lcv] = std::complex<float>(1, 0);
}
else
{
_dest[lcv] = std::complex<float>(-1, 0);
}
delay++;
delay %= _code_length;
}
}
/*
* Generates complex GLONASS L2 C/A code for the desired SV ID and sampled to specific sampling frequency
*/
void glonass_l2_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift)
{
// This function is based on the GNU software GPS for MATLAB in the Kay Borre book
std::complex<float> _code[511];
signed int _samplesPerCode, _codeValueIndex;
float _ts;
float _tc;
float aux;
const signed int _codeFreqBasis = 511000; //Hz
const signed int _codeLength = 511;
//--- Find number of samples per spreading code ----------------------------
_samplesPerCode = static_cast<signed int>(static_cast<double>(_fs) / static_cast<double>(_codeFreqBasis / _codeLength));
//--- Find time constants --------------------------------------------------
_ts = 1.0 / static_cast<float>(_fs); // Sampling period in sec
_tc = 1.0 / static_cast<float>(_codeFreqBasis); // C/A chip period in sec
glonass_l2_ca_code_gen_complex(_code, _chip_shift); //generate C/A code 1 sample per chip
for (signed int i = 0; i < _samplesPerCode; i++)
{
//=== Digitizing =======================================================
//--- Make index array to read C/A code values -------------------------
// The length of the index array depends on the sampling frequency -
// number of samples per millisecond (because one C/A code period is one
// millisecond).
// _codeValueIndex = ceil((_ts * ((float)i + 1)) / _tc) - 1;
aux = (_ts * (i + 1)) / _tc;
_codeValueIndex = auxCeil(aux) - 1;
//--- Make the digitized version of the C/A code -----------------------
// The "upsampled" code is made by selecting values form the CA code
// chip array (caCode) for the time instances of each sample.
if (i == _samplesPerCode - 1)
{
//--- Correct the last index (due to number rounding issues) -----------
_dest[i] = _code[_codeLength - 1];
}
else
{
_dest[i] = _code[_codeValueIndex]; //repeat the chip -> upsample
}
}
}

View File

@ -0,0 +1,47 @@
/*!
* \file glonass_l2_signal_processing.h
* \brief This class implements various functions for GLONASS L2 CA signals
* \author Damian Miralles, 2018, dmiralles2009(at)gmail.com
*
* Detailed description of the file here if needed.
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2017 (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_GLONASS_L2_SIGNAL_PROCESSING_H_
#define GNSS_SDR_GLONASS_L2_SIGNAL_PROCESSING_H_
#include <complex>
//!Generates complex GLONASS L2 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
void glonass_l2_ca_code_gen_complex(std::complex<float>* _dest, /*signed int _prn,*/ unsigned int _chip_shift);
//! Generates N complex GLONASS L2 C/A codes for the desired SV ID and code shift
void glonass_l2_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift, unsigned int _ncodes);
//! Generates complex GLONASS L2 C/A code for the desired SV ID and code shift
void glonass_l2_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift);
#endif /* GNSS_SDR_GLONASS_L2_SIGNAL_PROCESSING_H_ */

View File

@ -1,12 +1,12 @@
/*!
* \file gnss_sdr_sample_counter.cc
* \brief Simple block to report the current receiver time based on the output of the tracking or telemetry blocks
* \author Javier Arribas 2017. jarribas(at)cttc.es
* \author Javier Arribas 2018. jarribas(at)cttc.es
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
@ -32,40 +32,101 @@
#include "gnss_sdr_sample_counter.h"
#include "gnss_synchro.h"
#include <gnuradio/io_signature.h>
#include <cmath>
#include <iostream>
#include <string>
gnss_sdr_sample_counter::gnss_sdr_sample_counter() : gr::sync_block("sample_counter",
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(0, 0, 0))
gnss_sdr_sample_counter::gnss_sdr_sample_counter(double _fs, size_t _size) : gr::sync_decimator("sample_counter",
gr::io_signature::make(1, 1, _size),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
static_cast<unsigned int>(std::floor(_fs * 0.001)))
{
this->message_port_register_out(pmt::mp("sample_counter"));
last_T_rx_s = 0;
report_interval_s = 1; //default reporting 1 second
flag_enable_send_msg = false; //enable it for reporting time with asynchronous message
message_port_register_out(pmt::mp("sample_counter"));
set_max_noutput_items(1);
current_T_rx_ms = 0;
current_s = 0;
current_m = 0;
current_h = 0;
current_days = 0;
report_interval_ms = 1000; // default reporting 1 second
flag_enable_send_msg = false; // enable it for reporting time with asynchronous message
flag_m = false;
flag_h = false;
flag_days = false;
}
gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter()
gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, size_t _size)
{
gnss_sdr_sample_counter_sptr sample_counter_(new gnss_sdr_sample_counter());
gnss_sdr_sample_counter_sptr sample_counter_(new gnss_sdr_sample_counter(_fs, _size));
return sample_counter_;
}
int gnss_sdr_sample_counter::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items __attribute__((unused)))
int gnss_sdr_sample_counter::work(int noutput_items __attribute__((unused)),
gr_vector_const_void_star &input_items __attribute__((unused)),
gr_vector_void_star &output_items)
{
const Gnss_Synchro *in = reinterpret_cast<const Gnss_Synchro *>(input_items[0]); // input
double current_T_rx_s = in[noutput_items - 1].Tracking_sample_counter / static_cast<double>(in[noutput_items - 1].fs);
if ((current_T_rx_s - last_T_rx_s) > report_interval_s)
Gnss_Synchro *out = reinterpret_cast<Gnss_Synchro *>(output_items[0]);
out[0] = Gnss_Synchro();
if ((current_T_rx_ms % report_interval_ms) == 0)
{
std::cout << "Current receiver time: " << floor(current_T_rx_s) << " [s]" << std::endl;
if (flag_enable_send_msg == true)
current_s++;
if ((current_s % 60) == 0)
{
this->message_port_pub(pmt::mp("receiver_time"), pmt::from_double(current_T_rx_s));
current_s = 0;
current_m++;
flag_m = true;
if ((current_m % 60) == 0)
{
current_m = 0;
current_h++;
flag_h = true;
if ((current_h % 24) == 0)
{
current_h = 0;
current_days++;
flag_days = true;
}
}
}
if (flag_days)
{
std::string day;
if (current_days == 1)
{
day = " day ";
}
else
{
day = " days ";
}
std::cout << "Current receiver time: " << current_days << day << current_h << " h " << current_m << " min " << current_s << " s" << std::endl;
}
else
{
if (flag_h)
{
std::cout << "Current receiver time: " << current_h << " h " << current_m << " min " << current_s << " s" << std::endl;
}
else
{
if (flag_m)
{
std::cout << "Current receiver time: " << current_m << " min " << current_s << " s" << std::endl;
}
else
{
std::cout << "Current receiver time: " << current_s << " s" << std::endl;
}
}
}
if (flag_enable_send_msg)
{
message_port_pub(pmt::mp("receiver_time"), pmt::from_double(static_cast<double>(current_T_rx_ms) / 1000.0));
}
last_T_rx_s = current_T_rx_s;
}
return noutput_items;
current_T_rx_ms++;
return 1;
}

View File

@ -1,12 +1,12 @@
/*!
* \file gnss_sdr_sample_counter.h
* \brief Simple block to report the current receiver time based on the output of the tracking or telemetry blocks
* \author Javier Arribas 2017. jarribas(at)cttc.es
* \author Javier Arribas 2018. jarribas(at)cttc.es
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
@ -28,10 +28,10 @@
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_sample_counter_H_
#define GNSS_SDR_sample_counter_H_
#ifndef GNSS_SDR_SAMPLE_COUNTER_H_
#define GNSS_SDR_SAMPLE_COUNTER_H_
#include <gnuradio/sync_block.h>
#include <gnuradio/sync_decimator.h>
#include <boost/shared_ptr.hpp>
@ -39,20 +39,28 @@ class gnss_sdr_sample_counter;
typedef boost::shared_ptr<gnss_sdr_sample_counter> gnss_sdr_sample_counter_sptr;
gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter();
gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, size_t _size);
class gnss_sdr_sample_counter : public gr::sync_block
class gnss_sdr_sample_counter : public gr::sync_decimator
{
friend gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter();
gnss_sdr_sample_counter();
double last_T_rx_s;
double report_interval_s;
private:
gnss_sdr_sample_counter(double _fs, size_t _size);
long long int current_T_rx_ms; // Receiver time in ms since the beginning of the run
unsigned int current_s; // Receiver time in seconds, modulo 60
bool flag_m; // True if the receiver has been running for at least 1 minute
unsigned int current_m; // Receiver time in minutes, modulo 60
bool flag_h; // True if the receiver has been running for at least 1 hour
unsigned int current_h; // Receiver time in hours, modulo 24
bool flag_days; // True if the receiver has been running for at least 1 day
unsigned int current_days; // Receiver time in days since the beginning of the run
int report_interval_ms;
bool flag_enable_send_msg;
public:
friend gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, size_t _size);
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
};
#endif /*GNSS_SDR_sample_counter_H_*/
#endif /*GNSS_SDR_SAMPLE_COUNTER_H_*/

View File

@ -71,6 +71,23 @@ void gps_l2c_m_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
delete[] _code;
}
void gps_l2c_m_code_gen_float(float* _dest, unsigned int _prn)
{
int32_t* _code = new int32_t[GPS_L2_M_CODE_LENGTH_CHIPS];
if (_prn > 0 and _prn < 51)
{
gps_l2c_m_code(_code, _prn);
}
for (signed int i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++)
{
_dest[i] = 1.0 - 2.0 * static_cast<float>(_code[i]);
}
delete[] _code;
}
/*
* Generates complex GPS L2C M code for the desired SV ID and sampled to specific sampling frequency

View File

@ -38,7 +38,7 @@
//!Generates complex GPS L2C M code for the desired SV ID
void gps_l2c_m_code_gen_complex(std::complex<float>* _dest, unsigned int _prn);
void gps_l2c_m_code_gen_float(float* _dest, unsigned int _prn);
//! Generates complex GPS L2C M code for the desired SV ID, and sampled to specific sampling frequency
void gps_l2c_m_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, signed int _fs);

View File

@ -197,6 +197,22 @@ void gps_l5i_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
delete[] _code;
}
void gps_l5i_code_gen_float(float* _dest, unsigned int _prn)
{
int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS];
if (_prn > 0 and _prn < 51)
{
make_l5i(_code, _prn - 1);
}
for (signed int i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++)
{
_dest[i] = 1.0 - 2.0 * static_cast<float>(_code[i]);
}
delete[] _code;
}
/*
* Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency
@ -264,7 +280,22 @@ void gps_l5q_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
delete[] _code;
}
void gps_l5q_code_gen_float(float* _dest, unsigned int _prn)
{
int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS];
if (_prn > 0 and _prn < 51)
{
make_l5q(_code, _prn - 1);
}
for (signed int i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++)
{
_dest[i] = 1.0 - 2.0 * static_cast<float>(_code[i]);
}
delete[] _code;
}
/*
* Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency
*/

View File

@ -38,9 +38,11 @@
//!Generates complex GPS L5i M code for the desired SV ID
void gps_l5i_code_gen_complex(std::complex<float>* _dest, unsigned int _prn);
void gps_l5i_code_gen_float(float* _dest, unsigned int _prn);
//!Generates complex GPS L5q M code for the desired SV ID
void gps_l5q_code_gen_complex(std::complex<float>* _dest, unsigned int _prn);
void gps_l5q_code_gen_float(float* _dest, unsigned int _prn);
//! Generates complex GPS L5i M code for the desired SV ID, and sampled to specific sampling frequency
void gps_l5i_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, signed int _fs);

File diff suppressed because it is too large Load Diff

View File

@ -88,7 +88,6 @@ private:
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
//gr_kludge_copy_sptr kludge_copy_;
gr::blocks::copy::sptr kludge_copy_;
size_t item_size_;
conjugate_cc_sptr conjugate_cc_;

View File

@ -452,27 +452,27 @@ typedef struct
} alm_t;
typedef struct
{ /* GPS/QZS/GAL broadcast ephemeris type */
int sat; /* satellite number */
int iode, iodc; /* IODE,IODC */
int sva; /* SV accuracy (URA index) */
int svh; /* SV health (0:ok) */
int week; /* GPS/QZS: gps week, GAL: galileo week */
int code; /* GPS/QZS: code on L2, GAL/BDS: data sources */
int flag; /* GPS/QZS: L2 P data flag, BDS: nav type */
gtime_t toe, toc, ttr; /* Toe,Toc,T_trans */
/* SV orbit parameters */
double A, e, i0, OMG0, omg, M0, deln, OMGd, idot;
double crc, crs, cuc, cus, cic, cis;
double toes; /* Toe (s) in week */
double fit; /* fit interval (h) */
double f0, f1, f2; /* SV clock parameters (af0,af1,af2) */
double tgd[4]; /* group delay parameters */
/* GPS/QZS:tgd[0]=TGD */
/* GAL :tgd[0]=BGD E5a/E1,tgd[1]=BGD E5b/E1 */
/* BDS :tgd[0]=BGD1,tgd[1]=BGD2 */
double Adot, ndot; /* Adot,ndot for CNAV */
typedef struct { /* GPS/QZS/GAL broadcast ephemeris type */
int sat; /* satellite number */
int iode,iodc; /* IODE,IODC */
int sva; /* SV accuracy (URA index) */
int svh; /* SV health (0:ok) */
int week; /* GPS/QZS: gps week, GAL: galileo week */
int code; /* GPS/QZS: code on L2, GAL/BDS: data sources */
int flag; /* GPS/QZS: L2 P data flag, BDS: nav type */
gtime_t toe,toc,ttr; /* Toe,Toc,T_trans */
/* SV orbit parameters */
double A,e,i0,OMG0,omg,M0,deln,OMGd,idot;
double crc,crs,cuc,cus,cic,cis;
double toes; /* Toe (s) in week */
double fit; /* fit interval (h) */
double f0,f1,f2; /* SV clock parameters (af0,af1,af2) */
double tgd[4]; /* group delay parameters */
/* GPS/QZS:tgd[0]=TGD */
/* GAL :tgd[0]=BGD E5a/E1,tgd[1]=BGD E5b/E1 */
/* BDS :tgd[0]=BGD1,tgd[1]=BGD2 */
double isc[4]; /* GPS :isc[0]=ISCL1, isc[1]=ISCL2, isc[2]=ISCL5I, isc[3]=ISCL5Q */
double Adot,ndot; /* Adot,ndot for CNAV */
} eph_t;

View File

@ -116,7 +116,7 @@ geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const Glona
eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph)
{
eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0 };
//Galileo is the third satellite system for RTKLIB, so, add the required offset to discriminate Galileo ephemeris
rtklib_sat.sat = gal_eph.i_satellite_PRN + NSATGPS + NSATGLO;
rtklib_sat.A = gal_eph.A_1 * gal_eph.A_1;
@ -174,7 +174,7 @@ eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph)
eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph)
{
eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0 };
rtklib_sat.sat = gps_eph.i_satellite_PRN;
rtklib_sat.A = gps_eph.d_sqrt_A * gps_eph.d_sqrt_A;
rtklib_sat.M0 = gps_eph.d_M_0;
@ -199,9 +199,9 @@ eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph)
rtklib_sat.f1 = gps_eph.d_A_f1;
rtklib_sat.f2 = gps_eph.d_A_f2;
rtklib_sat.tgd[0] = gps_eph.d_TGD;
rtklib_sat.tgd[1] = 0;
rtklib_sat.tgd[2] = 0;
rtklib_sat.tgd[3] = 0;
rtklib_sat.tgd[1] = 0.0;
rtklib_sat.tgd[2] = 0.0;
rtklib_sat.tgd[3] = 0.0;
rtklib_sat.toes = gps_eph.d_Toe;
rtklib_sat.toc = gpst2time(rtklib_sat.week, gps_eph.d_Toc);
rtklib_sat.ttr = gpst2time(rtklib_sat.week, gps_eph.d_TOW);
@ -231,7 +231,7 @@ eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph)
eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph)
{
eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0 };
rtklib_sat.sat = gps_cnav_eph.i_satellite_PRN;
const double A_REF = 26559710.0; // See IS-GPS-200H, pp. 170
rtklib_sat.A = A_REF + gps_cnav_eph.d_DELTA_A;
@ -260,9 +260,13 @@ eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph)
rtklib_sat.f1 = gps_cnav_eph.d_A_f1;
rtklib_sat.f2 = gps_cnav_eph.d_A_f2;
rtklib_sat.tgd[0] = gps_cnav_eph.d_TGD;
rtklib_sat.tgd[1] = 0;
rtklib_sat.tgd[2] = 0;
rtklib_sat.tgd[3] = 0;
rtklib_sat.tgd[1] = 0.0;
rtklib_sat.tgd[2] = 0.0;
rtklib_sat.tgd[3] = 0.0;
rtklib_sat.isc[0] = gps_cnav_eph.d_ISCL1;
rtklib_sat.isc[1] = gps_cnav_eph.d_ISCL2;
rtklib_sat.isc[2] = gps_cnav_eph.d_ISCL5I;
rtklib_sat.isc[3] = gps_cnav_eph.d_ISCL5Q;
rtklib_sat.toes = gps_cnav_eph.d_Toe1;
rtklib_sat.toc = gpst2time(rtklib_sat.week, gps_cnav_eph.d_Toc);
rtklib_sat.ttr = gpst2time(rtklib_sat.week, gps_cnav_eph.d_TOW);

View File

@ -663,7 +663,7 @@ int satpos_sbas(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
*svh = -1;
return 0;
}
/* satellite postion and clock by broadcast ephemeris */
/* satellite position and clock by broadcast ephemeris */
if (!ephpos(time, teph, sat, nav, sbs->lcorr.iode, rs, dts, var, svh)) return 0;
/* sbas satellite correction (long term and fast) */
@ -734,7 +734,7 @@ int satpos_ssr(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
*svh = -1;
return 0;
}
/* satellite postion and clock by broadcast ephemeris */
/* satellite position and clock by broadcast ephemeris */
if (!ephpos(time, teph, sat, nav, ssr->iode, rs, dts, var, svh)) return 0;
/* satellite clock for gps, galileo and qzss */

View File

@ -78,18 +78,70 @@ double gettgd(int sat, const nav_t *nav)
return 0.0;
}
/* get isc parameter (m) -----------------------------------------------------*/
double getiscl1(int sat, const nav_t *nav)
{
for (int i = 0; i < nav->n; i++)
{
if (nav->eph[i].sat != sat) continue;
return SPEED_OF_LIGHT * nav->eph[i].isc[0];
}
return 0.0;
}
double getiscl2(int sat, const nav_t *nav)
{
for (int i = 0; i < nav->n; i++)
{
if (nav->eph[i].sat != sat) continue;
return SPEED_OF_LIGHT * nav->eph[i].isc[1];
}
return 0.0;
}
double getiscl5i(int sat, const nav_t *nav)
{
for (int i = 0; i < nav->n; i++)
{
if (nav->eph[i].sat != sat) continue;
return SPEED_OF_LIGHT * nav->eph[i].isc[2];
}
return 0.0;
}
double getiscl5q(int sat, const nav_t *nav)
{
for (int i = 0; i < nav->n; i++)
{
if (nav->eph[i].sat != sat) continue;
return SPEED_OF_LIGHT * nav->eph[i].isc[3];
}
return 0.0;
}
/* psendorange with code bias correction -------------------------------------*/
double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
int iter, const prcopt_t *opt, double *var)
{
const double *lam = nav->lam[obs->sat - 1];
double PC, P1, P2, P1_P2, P1_C1, P2_C2, gamma_;
int i = 0, j = 1, sys;
double PC = 0.0;
double P1 = 0.0;
double P2 = 0.0;
double P1_P2 = 0.0;
double P1_C1 = 0.0;
double P2_C2 = 0.0;
//Intersignal corrections (m). See GPS IS-200 CNAV message
double ISCl1 = 0.0;
double ISCl2 = 0.0;
double ISCl5i = 0.0;
double ISCl5q = 0.0;
double gamma_ = 0.0;
int i = 0;
int j = 1;
int sys = satsys(obs->sat, NULL);
*var = 0.0;
if (!(sys = satsys(obs->sat, NULL)))
if (sys == SYS_NONE)
{
trace(4, "prange: satsys NULL\n");
return 0.0;
@ -97,12 +149,11 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
/* L1-L2 for GPS/GLO/QZS, L1-L5 for GAL/SBS */
if (sys & (SYS_GAL | SYS_SBS))
if (sys == SYS_GAL or sys == SYS_SBS)
{
j = 2;
}
if (sys == SYS_GPS)
else if (sys == SYS_GPS or sys == SYS_GLO)
{
if (obs->code[1] != CODE_NONE)
{
@ -114,7 +165,7 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
}
}
if (NFREQ < 2 || lam[i] == 0.0 || lam[j] == 0.0)
if (lam[i] == 0.0 or lam[j] == 0.0)
{
trace(4, "prange: NFREQ<2||lam[i]==0.0||lam[j]==0.0\n");
printf("i: %d j:%d, lam[i]: %f lam[j] %f\n", i, j, lam[i], lam[j]);
@ -139,7 +190,11 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
}
}
}
gamma_ = std::pow(lam[j], 2.0) / std::pow(lam[i], 2.0); /* f1^2/f2^2 */
/* fL1^2 / fL2(orL5)^2 . See IS-GPS-200, p. 103 and Galileo ICD p. 48 */
if (sys == SYS_GPS or sys == SYS_GAL or sys == SYS_GLO)
{
gamma_ = std::pow(lam[j], 2.0) / std::pow(lam[i], 2.0);
}
P1 = obs->P[i];
P2 = obs->P[j];
P1_P2 = nav->cbias[obs->sat - 1][0];
@ -147,10 +202,20 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
P2_C2 = nav->cbias[obs->sat - 1][2];
/* if no P1-P2 DCB, use TGD instead */
if (P1_P2 == 0.0 && (sys & (SYS_GPS | SYS_GAL | SYS_QZS))) //CHECK!
if (P1_P2 == 0.0)
{
P1_P2 = (1.0 - gamma_) * gettgd(obs->sat, nav);
P1_P2 = gettgd(obs->sat, nav);
}
if (sys == SYS_GPS)
{
ISCl1 = getiscl1(obs->sat, nav);
ISCl2 = getiscl2(obs->sat, nav);
ISCl5i = getiscl5i(obs->sat, nav);
ISCl5q = getiscl5q(obs->sat, nav);
}
//CHECK IF IT IS STILL NEEDED
if (opt->ionoopt == IONOOPT_IFLC)
{ /* dual-frequency */
@ -170,25 +235,59 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
/* iono-free combination */
PC = (gamma_ * P1 - P2) / (gamma_ - 1.0);
}
////////////////////////////////////////////
else
{ /* single-frequency */
if ((obs->code[i] == CODE_NONE) && (obs->code[j] == CODE_NONE))
if (obs->code[i] == CODE_NONE and obs->code[j] == CODE_NONE)
{
return 0.0;
}
else if ((obs->code[i] != CODE_NONE) && (obs->code[j] == CODE_NONE))
else if (obs->code[i] != CODE_NONE and obs->code[j] == CODE_NONE)
{
P1 += P1_C1; /* C1->P1 */
PC = P1 - P1_P2 / (1.0 - gamma_);
PC = P1 + P1_P2;
}
else if ((obs->code[i] == CODE_NONE) && (obs->code[j] != CODE_NONE))
else if (obs->code[i] == CODE_NONE and obs->code[j] != CODE_NONE)
{
P2 += P2_C2; /* C2->P2 */
PC = P2 - gamma_ * P1_P2 / (1.0 - gamma_);
if (sys == SYS_GPS)
{
P2 += P2_C2; /* C2->P2 */
//PC = P2 - gamma_ * P1_P2 / (1.0 - gamma_);
if (obs->code[j] == CODE_L2S) //L2 single freq.
{
PC = P2 + P1_P2 - ISCl2;
}
else if (obs->code[j] == CODE_L5X) //L5 single freq.
{
PC = P2 + P1_P2 - ISCl5i;
}
}
else if (sys == SYS_GAL or sys == SYS_GLO) // Gal. E5a single freq.
{
P2 += P2_C2; /* C2->P2 */
PC = P2 - gamma_ * P1_P2 / (1.0 - gamma_);
}
}
/* dual-frequency */
else
else if (sys == SYS_GPS)
{
if (obs->code[j] == CODE_L2S) /* L1 + L2 */
{
//By the moment, GPS L2 pseudoranges are not used
//PC = (P2 + ISCl2 - gamma_ * (P1 + ISCl1)) / (1.0 - gamma_) - P1_P2;
P1 += P1_C1; /* C1->P1 */
PC = P1 + P1_P2;
}
else if (obs->code[j] == CODE_L5X) /* L1 + L5 */
{
//By the moment, GPS L5 pseudoranges are not used
//PC = (P2 + ISCl5i - gamma_ * (P1 + ISCl5i)) / (1.0 - gamma_) - P1_P2;
P1 += P1_C1; /* C1->P1 */
PC = P1 + P1_P2;
}
}
else if (sys == SYS_GAL or sys == SYS_GLO) /* E1 + E5a */
{
P1 += P1_C1;
P2 += P2_C2;
@ -199,9 +298,7 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
{
PC -= P1_C1;
} /* sbas clock based C1 */
*var = std::pow(ERR_CBIAS, 2.0);
return PC;
}
@ -768,7 +865,7 @@ int pntpos(const obsd_t *obs, int n, const nav_t *nav,
opt_.ionoopt = IONOOPT_BRDC;
opt_.tropopt = TROPOPT_SAAS;
}
/* satellite positons, velocities and clocks */
/* satellite positions, velocities and clocks */
satposs(sol->time, obs, n, nav, opt_.sateph, rs, dts, var, svh);
/* estimate receiver position with pseudorange */

View File

@ -69,6 +69,12 @@ double varerr(const prcopt_t *opt, double el, int sys);
/* get tgd parameter (m) -----------------------------------------------------*/
double gettgd(int sat, const nav_t *nav);
/* get isc parameter (m) -----------------------------------------------------*/
double getiscl1(int sat, const nav_t *nav);
double getiscl2(int sat, const nav_t *nav);
double getiscl5i(int sat, const nav_t *nav);
double getiscl5q(int sat, const nav_t *nav);
/* psendorange with code bias correction -------------------------------------*/
double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
int iter, const prcopt_t *opt, double *var);

View File

@ -425,7 +425,7 @@ int fix_amb_ROUND(rtk_t *rtk, int *sat1, int *sat2, const int *NW, int n)
sat2[m] = sat2[i];
NC[m++] = BC;
}
/* select fixed ambiguities by dependancy check */
/* select fixed ambiguities by dependency check */
m = sel_amb(sat1, sat2, NC, var, m);
/* fixed solution */

View File

@ -79,7 +79,7 @@
const double MIN_ARC_GAP = 300.0; /* min arc gap (s) */
const double CONST_AMB = 0.001; /* constraint to fixed ambiguity */
const double THRES_RES = 0.3; /* threashold of residuals test (m) */
const double THRES_RES = 0.3; /* threshold of residuals test (m) */
const double LOG_PI = 1.14472988584940017; /* log(pi) */
const double SQRT2 = 1.41421356237309510; /* sqrt(2) */

View File

@ -843,7 +843,7 @@ void satantoff(gtime_t time, const double *rs, int sat, const nav_t *nav,
* args : gtime_t time I time (gpst)
* int sat I satellite number
* nav_t *nav I navigation data
* int opt I sat postion option
* int opt I sat position option
* (0: center of mass, 1: antenna phase center)
* double *rs O sat position and velocity (ecef)
* {x,y,z,vx,vy,vz} (m|m/s)

View File

@ -69,7 +69,7 @@ int init_rtcm(rtcm_t *rtcm)
obsd_t data0 = {{0, 0.0}, 0, 0, {0}, {0}, {0}, {0.0}, {0.0}, {0.0}};
eph_t eph0 = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
geph_t geph0 = {0, -1, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0.0}, {0.0}, {0.0},
0.0, 0.0, 0.0};
ssr_t ssr0 = {{{0, 0.0}}, {0.0}, {0}, 0, 0, 0, 0, {0.0}, {0.0}, {0.0}, 0.0, {0.0}, {0.0}, {0.0}, 0.0, 0.0, '0'};
@ -315,7 +315,7 @@ int input_rtcm3(rtcm_t *rtcm, unsigned char data)
/* input rtcm 2 message from file ----------------------------------------------
* fetch next rtcm 2 message and input a messsage from file
* fetch next rtcm 2 message and input a message from file
* args : rtcm_t *rtcm IO rtcm control struct
* FILE *fp I file pointer
* return : status (-2: end of file, -1...10: same as above)
@ -337,7 +337,7 @@ int input_rtcm2f(rtcm_t *rtcm, FILE *fp)
/* input rtcm 3 message from file ----------------------------------------------
* fetch next rtcm 3 message and input a messsage from file
* fetch next rtcm 3 message and input a message from file
* args : rtcm_t *rtcm IO rtcm control struct
* FILE *fp I file pointer
* return : status (-2: end of file, -1...10: same as above)

View File

@ -219,7 +219,7 @@ int decode_type17(rtcm_t *rtcm)
{
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
double toc, sqrtA;
int i = 48, week, prn, sat;

View File

@ -846,7 +846,7 @@ int decode_type1019(rtcm_t *rtcm)
{
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
double toc, sqrtA;
char *msg;
int i = 24 + 12, prn, sat, week, sys = SYS_GPS;
@ -1056,7 +1056,7 @@ int decode_type1021(rtcm_t *rtcm __attribute__((unused)))
}
/* decode type 1022: moledenski-badekas transfromation -----------------------*/
/* decode type 1022: moledenski-badekas transformation -----------------------*/
int decode_type1022(rtcm_t *rtcm __attribute__((unused)))
{
trace(2, "rtcm3 1022: not supported message\n");
@ -1293,7 +1293,7 @@ int decode_type1044(rtcm_t *rtcm)
{
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
double toc, sqrtA;
char *msg;
int i = 24 + 12, prn, sat, week, sys = SYS_QZS;
@ -1398,7 +1398,7 @@ int decode_type1045(rtcm_t *rtcm)
{
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
double toc, sqrtA;
char *msg;
int i = 24 + 12, prn, sat, week, e5a_hs, e5a_dvs, sys = SYS_GAL;
@ -1502,7 +1502,7 @@ int decode_type1046(rtcm_t *rtcm)
{
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
double toc, sqrtA;
char *msg;
int i = 24 + 12, prn, sat, week, e5a_hs, e5a_dvs, sys = SYS_GAL;
@ -1606,7 +1606,7 @@ int decode_type1047(rtcm_t *rtcm)
{
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
;
double toc, sqrtA;
char *msg;
@ -1716,7 +1716,7 @@ int decode_type63(rtcm_t *rtcm)
{
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
double toc, sqrtA;
char *msg;
int i = 24 + 12, prn, sat, week, sys = SYS_BDS;
@ -2699,7 +2699,7 @@ void save_msm_obs(rtcm_t *rtcm, int sys, msm_h_t *h, const double *r,
/* signal to rinex obs type */
code[i] = obs2code(sig[i], freq + i);
/* freqency index for beidou */
/* frequency index for beidou */
if (sys == SYS_BDS)
{
if (freq[i] == 5)

View File

@ -253,12 +253,11 @@ const unsigned int tbl_CRC24Q[] = {
0x42FA2F, 0xC4B6D4, 0xC82F22, 0x4E63D9, 0xD11CCE, 0x575035, 0x5BC9C3, 0xDD8538};
extern "C"
{
void dgemm_(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *);
extern void dgetrf_(int *, int *, double *, int *, int *, int *);
extern void dgetri_(int *, double *, int *, int *, double *, int *, int *);
extern void dgetrs_(char *, int *, int *, double *, int *, int *, double *, int *, int *);
extern "C" {
void dgemm_(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *);
extern void dgetrf_(int *, int *, double *, int *, int *, int *);
extern void dgetri_(int *, double *, int *, int *, double *, int *, int *);
extern void dgetrs_(char *, int *, int *, double *, int *, int *, double *, int *, int *);
}
@ -1388,10 +1387,10 @@ double time2gpst(gtime_t t, int *week)
{
gtime_t t0 = epoch2time(gpst0);
time_t sec = t.time - t0.time;
int w = (int)(sec / (86400 * 7));
int w = static_cast<int>(sec / 604800);
if (week) *week = w;
return (double)(sec - (double)w * 86400 * 7) + t.sec;
return (static_cast<double>(sec - static_cast<time_t>(w * 604800)) + t.sec);
}
@ -1819,7 +1818,7 @@ unsigned int tickget(void)
/* sleep ms --------------------------------------------------------------------
* sleep ms
* args : int ms I miliseconds to sleep (<0:no sleep)
* args : int ms I milliseconds to sleep (<0:no sleep)
* return : none
*-----------------------------------------------------------------------------*/
void sleepms(int ms)
@ -1884,7 +1883,7 @@ double dms2deg(const double *dms)
}
/* transform ecef to geodetic postion ------------------------------------------
/* transform ecef to geodetic position ------------------------------------------
* transform ecef position to geodetic position
* args : double *r I ecef position {x,y,z} (m)
* double *pos O geodetic position {lat,lon,h} (rad,m)
@ -1926,8 +1925,8 @@ void pos2ecef(const double *pos, double *r)
}
/* ecef to local coordinate transfromation matrix ------------------------------
* compute ecef to local coordinate transfromation matrix
/* ecef to local coordinate transformation matrix ------------------------------
* compute ecef to local coordinate transformation matrix
* args : double *pos I geodetic position {lat,lon} (rad)
* double *E O ecef to local coord transformation matrix (3x3)
* return : none
@ -2223,7 +2222,7 @@ void eci2ecef(gtime_t tutc, const double *erpv, double *U, double *gmst)
matmul("NN", 3, 3, 3, 1.0, R1, R2, 0.0, R);
matmul("NN", 3, 3, 3, 1.0, R, R3, 0.0, N); /* N=Rx(-eps)*Rz(-dspi)*Rx(eps) */
/* greenwich aparent sidereal time (rad) */
/* greenwich apparent sidereal time (rad) */
gmst_ = utc2gmst(tutc_, erpv[2]);
gast = gmst_ + dpsi * cos(eps);
gast += (0.00264 * sin(f[4]) + 0.000063 * sin(2.0 * f[4])) * AS2R;
@ -2993,7 +2992,7 @@ int readnav(const char *file, nav_t *nav)
{
FILE *fp;
eph_t eph0 = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0};
geph_t geph0 = {0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {}, {}, {}, 0.0, 0.0, 0.0};
char buff[4096], *p;
long toe_time, tof_time, toc_time, ttr_time;
@ -4166,7 +4165,7 @@ void sunmoonpos(gtime_t tutc, const double *erpv, double *rsun,
/* eci to ecef transformation matrix */
eci2ecef(tutc, erpv, U, &gmst_);
/* sun and moon postion in ecef */
/* sun and moon position in ecef */
if (rsun) matmul("NN", 3, 1, 3, 1.0, U, rs, 0.0, rsun);
if (rmoon) matmul("NN", 3, 1, 3, 1.0, U, rm, 0.0, rmoon);
if (gmst) *gmst = gmst_;

View File

@ -599,7 +599,7 @@ void udpos(rtk_t *rtk, double tt)
for (i = 0; i < 3; i++) initx_rtk(rtk, rtk->sol.rr[i], VAR_POS, i);
return;
}
/* check variance of estimated postion */
/* check variance of estimated position */
for (i = 0; i < 3; i++)
{
var += rtk->P[i + i * rtk->nx];
@ -2223,7 +2223,7 @@ void rtkfree(rtk_t *rtk)
* .vs [r] O data valid single (r=0:rover,1:base)
* .resp [f] O freq(f+1) pseudorange residual (m)
* .resc [f] O freq(f+1) carrier-phase residual (m)
* .vsat [f] O freq(f+1) data vaild (0:invalid,1:valid)
* .vsat [f] O freq(f+1) data valid (0:invalid,1:valid)
* .fix [f] O freq(f+1) ambiguity flag
* (0:nodata,1:float,2:fix,3:hold)
* .slip [f] O freq(f+1) slip flag
@ -2262,7 +2262,7 @@ int rtkpos(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav)
traceobs(4, obs, n);
/*trace(5,"nav=\n"); tracenav(5,nav);*/
/* set base staion position */
/* set base station position */
if (opt->refpos <= POSOPT_RINEX && opt->mode != PMODE_SINGLE &&
opt->mode != PMODE_MOVEB)
{

View File

@ -210,7 +210,7 @@ void updatesvr(rtksvr_t *svr, int ret, obs_t *obs, nav_t *nav, int sat,
svr->nmsg[index][2]++;
}
else if (ret == 5)
{ /* antenna postion parameters */
{ /* antenna position parameters */
if (svr->rtk.opt.refpos == 4 && index == 1)
{
for (i = 0; i < 3; i++)
@ -592,7 +592,7 @@ int rtksvrinit(rtksvr_t *svr)
'0', '0', '0', 0, 0, 0};
eph_t eph0 = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, 0.0, 0.0};
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
geph_t geph0 = {0, -1, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0.0}, {0.0}, {0.0},
0.0, 0.0, 0.0};
seph_t seph0 = {0, {0, 0.0}, {0, 0.0}, 0, 0, {0.0}, {0.0}, {0.0}, 0.0, 0.0};

View File

@ -616,10 +616,10 @@ int cmpmsgs(const void *p1, const void *p2)
* (gtime_t te I end time )
* sbs_t *sbs IO sbas messages
* return : number of sbas messages
* notes : sbas message are appended and sorted. before calling the funciton,
* notes : sbas message are appended and sorted. before calling the function,
* sbs->n, sbs->nmax and sbs->msgs must be set properly. (initially
* sbs->n=sbs->nmax=0, sbs->msgs=NULL)
* only the following file extentions after wild card expanded are valid
* only the following file extensions after wild card expanded are valid
* to read. others are skipped
* .sbs, .SBS, .ems, .EMS
*-----------------------------------------------------------------------------*/

View File

@ -150,7 +150,7 @@ void covtosol(const double *P, sol_t *sol)
}
/* decode nmea gprmc: recommended minumum data for gps -----------------------*/
/* decode nmea gprmc: recommended minimum data for gps -----------------------*/
int decode_nmearmc(char **val, int n, sol_t *sol)
{
double tod = 0.0, lat = 0.0, lon = 0.0, vel = 0.0, dir = 0.0, date = 0.0, ang = 0.0, ep[6];
@ -219,7 +219,7 @@ int decode_nmearmc(char **val, int n, sol_t *sol)
sol->stat = mode == 'D' ? SOLQ_DGPS : SOLQ_SINGLE;
sol->ns = 0;
sol->type = 0; /* postion type = xyz */
sol->type = 0; /* position type = xyz */
trace(5, "decode_nmearmc: %s rr=%.3f %.3f %.3f stat=%d ns=%d vel=%.2f dir=%.0f ang=%.0f mew=%c mode=%c\n",
time_str(sol->time, 0), sol->rr[0], sol->rr[1], sol->rr[2], sol->stat, sol->ns,
@ -310,7 +310,7 @@ int decode_nmeagga(char **val, int n, sol_t *sol)
sol->stat = 0 <= solq && solq <= 8 ? solq_nmea[solq] : SOLQ_NONE;
sol->ns = nrcv;
sol->type = 0; /* postion type = xyz */
sol->type = 0; /* position type = xyz */
trace(5, "decode_nmeagga: %s rr=%.3f %.3f %.3f stat=%d ns=%d hdop=%.1f ua=%c um=%c\n",
time_str(sol->time, 0), sol->rr[0], sol->rr[1], sol->rr[2], sol->stat, sol->ns,
@ -453,7 +453,7 @@ int decode_solxyz(char *buff, const solopt_t *opt, sol_t *sol)
if (i < n) sol->age = (float)val[i++];
if (i < n) sol->ratio = (float)val[i];
sol->type = 0; /* postion type = xyz */
sol->type = 0; /* position type = xyz */
if (MAXSOLQ < sol->stat) sol->stat = SOLQ_NONE;
return 1;
@ -512,7 +512,7 @@ int decode_solllh(char *buff, const solopt_t *opt, sol_t *sol)
if (i < n) sol->age = (float)val[i++];
if (i < n) sol->ratio = (float)val[i];
sol->type = 0; /* postion type = xyz */
sol->type = 0; /* position type = xyz */
if (MAXSOLQ < sol->stat) sol->stat = SOLQ_NONE;
return 1;
@ -558,7 +558,7 @@ int decode_solenu(char *buff, const solopt_t *opt, sol_t *sol)
if (i < n) sol->age = (float)val[i++];
if (i < n) sol->ratio = (float)val[i];
sol->type = 1; /* postion type = enu */
sol->type = 1; /* position type = enu */
if (MAXSOLQ < sol->stat) sol->stat = SOLQ_NONE;
return 1;
@ -1798,7 +1798,7 @@ int outsols(unsigned char *buff, const sol_t *sol, const double *rb,
/* output solution extended ----------------------------------------------------
* output solution exteneded infomation
* output solution exteneded information
* args : unsigned char *buff IO output buffer
* sol_t *sol I solution
* ssat_t *ssat I satellite status
@ -1892,7 +1892,7 @@ void outsol(FILE *fp, const sol_t *sol, const double *rb,
/* output solution extended ----------------------------------------------------
* output solution exteneded infomation to file
* output solution exteneded information to file
* args : FILE *fp I output file pointer
* sol_t *sol I solution
* ssat_t *ssat I satellite status

View File

@ -1916,7 +1916,7 @@ void strunlock(stream_t *stream) { rtk_unlock(&stream->lock); }
/* read stream -----------------------------------------------------------------
* read data from stream (unblocked)
* args : stream_t *stream I stream
* unsinged char *buff O data buffer
* unsigned char *buff O data buffer
* int n I maximum data length
* return : read data length
* notes : if no data, return immediately with no data
@ -1978,7 +1978,7 @@ int strread(stream_t *stream, unsigned char *buff, int n)
/* write stream ----------------------------------------------------------------
* write data to stream (unblocked)
* args : stream_t *stream I stream
* unsinged char *buff I data buffer
* unsigned char *buff I data buffer
* int n I data length
* return : status (0:error, 1:ok)
* notes : write data to buffer and return immediately

View File

@ -145,7 +145,7 @@ INLINE_INHERITED_MEMB = NO
# shortest path that makes the file name unique will be used
# The default value is: YES.
FULL_PATH_NAMES = YES
FULL_PATH_NAMES = NO
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
# Stripping is only done if one of the specified strings matches the left-hand

View File

@ -7,8 +7,8 @@ and contact information about the original VOLK library.
The boilerplate of this code was initially generated with
```volk_modtool```, an application provided by VOLK that creates the
skeleton than can then be filled with custom kernels. Some modifications
were added to accomodate the specificities of Global Navigation
skeleton that can then be filled with custom kernels. Some modifications
were added to accommodate the specificities of Global Navigation
Satellite Systems (GNSS) signal processing. Those changes are clearly
indicated in the source code, and do not break compatibility.
@ -39,7 +39,7 @@ This library is automatically built and installed along with GNSS-SDR if
it is not found by CMake on your system at configure time.
However, you can install and use VOLK_GNSSSDR kernels as you use VOLK's,
independently from GNSS-SDR.
independently of GNSS-SDR.
First, make sure that the required dependencies are installed in your
machine:

View File

@ -16,8 +16,8 @@
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VOLK_VOLK_OPTION_HELPERS_H
#define VOLK_VOLK_OPTION_HELPERS_H
#ifndef VOLK_GNSSSDR_OPTION_HELPERS_H
#define VOLK_GNSSSDR_OPTION_HELPERS_H
#include <climits>
#include <cstring>
@ -71,4 +71,4 @@ private:
};
#endif //VOLK_VOLK_OPTION_HELPERS_H
#endif //VOLK_GNSSSDR_OPTION_HELPERS_H

View File

@ -148,7 +148,7 @@ int main(int argc, char *argv[])
}
catch (std::string &error)
{
std::cerr << "Caught Exception in 'run_volk_gnssdr_tests': " << error << std::endl;
std::cerr << "Caught Exception in 'run_volk_gnsssdr_tests': " << error << std::endl;
}
}
}

View File

@ -32,7 +32,7 @@
#include <string> // for string
#include <vector> // for vector
class volk_test_results_t;
class volk_gnsssdr_test_results_t;
void read_results(std::vector<volk_gnsssdr_test_results_t> *results);

View File

@ -22,24 +22,40 @@ if(DEFINED __INCLUDED_VOLK_ADD_TEST)
endif()
set(__INCLUDED_VOLK_ADD_TEST TRUE)
########################################################################
# Generate a test executable which can be used in ADD_TEST to call
# various subtests.
#
# SOURCES - sources for the test
# TARGET_DEPS - build target dependencies (e.g., libraries)
########################################################################
function(VOLK_GEN_TEST executable_name)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(VOLK_TEST "" "" "SOURCES;TARGET_DEPS;EXTRA_LIB_DIRS;ENVIRONS;ARGS" ${ARGN})
add_executable(${executable_name} ${VOLK_TEST_SOURCES})
target_link_libraries(${executable_name} ${VOLK_TEST_TARGET_DEPS})
endfunction()
########################################################################
# Add a unit test and setup the environment for it.
# Encloses ADD_TEST, with additional functionality to create a shell
# script that sets the environment to gain access to in-build binaries
# properly. The following variables are used to pass in settings:
# A test executable has to be generated with VOLK_GEN_TEST beforehand.
# The executable name has to be passed as argument.
#
# NAME - the test name
# SOURCES - sources for the test
# TARGET_DEPS - build target dependencies (e.g., libraries)
# EXTRA_LIB_DIRS - other directories for the library path
# ENVIRONS - other environment key/value pairs
# ARGS - arguments for the test
########################################################################
function(VOLK_ADD_TEST test_name)
function(VOLK_ADD_TEST test_name executable_name)
#parse the arguments for component names
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(VOLK_TEST "" "" "SOURCES;TARGET_DEPS;EXTRA_LIB_DIRS;ENVIRONS;ARGS" ${ARGN})
CMAKE_PARSE_ARGUMENTS(VOLK_TEST "" "" "TARGET_DEPS;EXTRA_LIB_DIRS;ENVIRONS;ARGS" ${ARGN})
#set the initial environs to use
set(environs ${VOLK_TEST_ENVIRONS})
@ -65,7 +81,7 @@ function(VOLK_ADD_TEST test_name)
#"add_test" command, via the $<FOO:BAR> operator; make sure the
#test's directory is first, since it ($1) is prepended to PATH.
unset(TARGET_DIR_LIST)
foreach(target ${test_name} ${VOLK_TEST_TARGET_DEPS})
foreach(target ${executable_name} ${VOLK_TEST_TARGET_DEPS})
list(APPEND TARGET_DIR_LIST "\$<TARGET_FILE_DIR:${target}>")
endforeach()
@ -134,18 +150,17 @@ function(VOLK_ADD_TEST test_name)
file(APPEND ${sh_file} "export ${environ}\n")
endforeach(environ)
set(VOLK_TEST_ARGS "${test_name}")
#redo the test args to have a space between each
string(REPLACE ";" " " VOLK_TEST_ARGS "${VOLK_TEST_ARGS}")
#finally: append the test name to execute
file(APPEND ${sh_file} ${test_name} " " ${VOLK_TEST_ARGS} "\n")
file(APPEND ${sh_file} "${CMAKE_CROSSCOMPILING_EMULATOR} ${executable_name} ${VOLK_TEST_ARGS}\n")
#make the shell file executable
execute_process(COMMAND chmod +x ${sh_file})
add_executable(${test_name} ${VOLK_TEST_SOURCES})
target_link_libraries(${test_name} ${VOLK_TEST_TARGET_DEPS})
#add the shell file as the test to execute;
#use the form that allows for $<FOO:BAR> substitutions,
#then combine the script arguments inside the script.
@ -196,10 +211,8 @@ function(VOLK_ADD_TEST test_name)
file(APPEND ${bat_file} ${test_name} " " ${VOLK_TEST_ARGS} "\n")
file(APPEND ${bat_file} "\n")
add_executable(${test_name} ${VOLK_TEST_SOURCES})
target_link_libraries(${test_name} ${VOLK_TEST_TARGET_DEPS})
add_test(${test_name} ${bat_file})
endif(WIN32)
endfunction(VOLK_ADD_TEST)

View File

@ -29,6 +29,6 @@ if(${PACKAGE_FIND_VERSION_MAJOR} EQUAL ${MAJOR_VERSION})
if(NOT ${PACKAGE_FIND_VERSION_PATCH} GREATER ${MAINT_VERSION})
set(PACKAGE_VERSION_EXACT 1) # exact match for API version
set(PACKAGE_VERSION_COMPATIBLE 1) # compat for minor/patch version
endif(NOT ${PACKAGE_FIND_VERSION_PATCH} GREATER ${MINOR_VERSION})
endif(${PACKAGE_FIND_VERSION_MINOR} EQUAL ${API_COMPAT})
endif(NOT ${PACKAGE_FIND_VERSION_PATCH} GREATER ${MAINT_VERSION})
endif(${PACKAGE_FIND_VERSION_MINOR} EQUAL ${MINOR_VERSION})
endif(${PACKAGE_FIND_VERSION_MAJOR} EQUAL ${MAJOR_VERSION})

View File

@ -187,7 +187,7 @@ static inline void volk_gnsssdr_16ic_x2_dot_prod_16ic_u_sse2(lv_16sc_t* out, con
for (number = 0; number < sse_iters; number++)
{
//std::complex<T> memory structure: real part -> reinterpret_cast<cv T*>(a)[2*i]
//imaginery part -> reinterpret_cast<cv T*>(a)[2*i + 1]
//imaginary part -> reinterpret_cast<cv T*>(a)[2*i + 1]
// a[127:0]=[a3.i,a3.r,a2.i,a2.r,a1.i,a1.r,a0.i,a0.r]
a = _mm_loadu_si128((__m128i*)_in_a); //load (2 byte imag, 2 byte real) x 4 into 128 bits reg
__VOLK_GNSSSDR_PREFETCH(_in_a + 8);

View File

@ -94,7 +94,7 @@ static inline void volk_gnsssdr_16ic_x2_multiply_16ic_a_sse2(lv_16sc_t* out, con
for (number = 0; number < sse_iters; number++)
{
//std::complex<T> memory structure: real part -> reinterpret_cast<cv T*>(a)[2*i]
//imaginery part -> reinterpret_cast<cv T*>(a)[2*i + 1]
//imaginary part -> reinterpret_cast<cv T*>(a)[2*i + 1]
// a[127:0]=[a3.i,a3.r,a2.i,a2.r,a1.i,a1.r,a0.i,a0.r]
a = _mm_load_si128((__m128i*)_in_a); //load (2 byte imag, 2 byte real) x 4 into 128 bits reg
b = _mm_load_si128((__m128i*)_in_b);
@ -148,7 +148,7 @@ static inline void volk_gnsssdr_16ic_x2_multiply_16ic_u_sse2(lv_16sc_t* out, con
for (number = 0; number < sse_iters; number++)
{
//std::complex<T> memory structure: real part -> reinterpret_cast<cv T*>(a)[2*i]
//imaginery part -> reinterpret_cast<cv T*>(a)[2*i + 1]
//imaginary part -> reinterpret_cast<cv T*>(a)[2*i + 1]
// a[127:0]=[a3.i,a3.r,a2.i,a2.r,a1.i,a1.r,a0.i,a0.r]
a = _mm_loadu_si128((__m128i*)_in_a); //load (2 byte imag, 2 byte real) x 4 into 128 bits reg
b = _mm_loadu_si128((__m128i*)_in_b);

View File

@ -6,7 +6,7 @@
* </ul>
*
* VOLK_GNSSSDR kernel that esamples N 16 bits integer short complex vectors using zero hold resample algorithm.
* It is optimized to resample a sigle GNSS local code signal replica into N vectors fractional-resampled and fractional-delayed
* It is optimized to resample a single GNSS local code signal replica into N vectors fractional-resampled and fractional-delayed
* (i.e. it creates the Early, Prompt, and Late code replicas)
*
* -------------------------------------------------------------------------
@ -145,7 +145,7 @@ static inline void volk_gnsssdr_16ic_xn_resampler_fast_16ic_xn_a_sse2(lv_16sc_t*
//common to all outputs
_code_phase_out = _mm_mul_ps(_code_phase_step_chips, _4output_index); //compute the code phase point with the phase step
//output vector dependant (different code phase offset)
//output vector dependent (different code phase offset)
for (current_vector = 0; current_vector < num_out_vectors; current_vector++)
{
tmp_rem_code_phase_chips = rem_code_phase_chips[current_vector] - 0.5f; // adjust offset to perform correct rounding (chip transition at 0)
@ -241,7 +241,7 @@ static inline void volk_gnsssdr_16ic_xn_resampler_fast_16ic_xn_u_sse2(lv_16sc_t*
//common to all outputs
_code_phase_out = _mm_mul_ps(_code_phase_step_chips, _4output_index); //compute the code phase point with the phase step
//output vector dependant (different code phase offset)
//output vector dependent (different code phase offset)
for (current_vector = 0; current_vector < num_out_vectors; current_vector++)
{
tmp_rem_code_phase_chips = rem_code_phase_chips[current_vector] - 0.5f; // adjust offset to perform correct rounding (chip transition at 0)
@ -339,7 +339,7 @@ static inline void volk_gnsssdr_16ic_xn_resampler_fast_16ic_xn_neon(lv_16sc_t**
//common to all outputs
_code_phase_out = vmulq_f32(_code_phase_step_chips, _4output_index); //compute the code phase point with the phase step
//output vector dependant (different code phase offset)
//output vector dependent (different code phase offset)
for (current_vector = 0; current_vector < num_out_vectors; current_vector++)
{
tmp_rem_code_phase_chips = rem_code_phase_chips[current_vector] - 0.5f; // adjust offset to perform correct rounding (chip transition at 0)

View File

@ -345,7 +345,7 @@ macro(gen_template tmpl output)
)
endmacro(gen_template)
make_directory(${PROJECT_BINARY_DIR}/include/volk_gnsssdr)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/include/volk_gnsssdr)
gen_template(${PROJECT_SOURCE_DIR}/tmpl/volk_gnsssdr.tmpl.h ${PROJECT_BINARY_DIR}/include/volk_gnsssdr/volk_gnsssdr.h)
gen_template(${PROJECT_SOURCE_DIR}/tmpl/volk_gnsssdr.tmpl.c ${PROJECT_BINARY_DIR}/lib/volk_gnsssdr.c)
@ -604,18 +604,24 @@ if(ENABLE_TESTING)
#include Boost headers
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
make_directory(${CMAKE_CURRENT_BINARY_DIR}/.unittest)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/.unittest)
set_source_files_properties(
${CMAKE_CURRENT_SOURCE_DIR}/testqa.cc PROPERTIES
COMPILE_DEFINITIONS "BOOST_TEST_DYN_LINK;BOOST_TEST_MAIN"
)
include(VolkAddTest)
VOLK_ADD_TEST(test_all
VOLK_GEN_TEST("volk_gnsssdr_test_all"
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/testqa.cc
${CMAKE_CURRENT_SOURCE_DIR}/qa_utils.cc
${CMAKE_CURRENT_SOURCE_DIR}/qa_utils.cc
TARGET_DEPS volk_gnsssdr
)
)
foreach(kernel ${h_files})
get_filename_component(kernel ${kernel} NAME)
string(REPLACE ".h" "" kernel ${kernel})
if(NOT ${kernel} MATCHES puppet*)
VOLK_ADD_TEST(${kernel} "volk_gnsssdr_test_all")
endif(NOT ${kernel} MATCHES puppet*)
endforeach()
endif(ENABLE_TESTING)

View File

@ -16,14 +16,10 @@
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*/
#include "volk_gnsssdr/volk_gnsssdr.h" // for volk_gnsssdr_func_desc_t
#include "qa_utils.h"
#include "volk_gnsssdr/volk_gnsssdr.h" // for volk_gnsssdr_func_desc_t
#include "volk_gnsssdr/volk_gnsssdr_malloc.h" // for volk_gnsssdr_free, volk_gnsssdr_malloc
#include <boost/foreach.hpp> // for auto_any_base
#include <boost/lexical_cast.hpp> // for lexical_cast
#include <boost/token_functions.hpp> // for char_separator
#include <boost/token_iterator.hpp> // for token_iterator
#include <boost/tokenizer.hpp> // for tokenizer
#include <volk_gnsssdr/volk_gnsssdr_malloc.h> // for volk_gnsssdr_free, volk_gnsssdr_malloc
#include <cassert> // for assert
#include <chrono> // for system_clock, duration,...
#include <cmath> // for sqrt, fabs, abs
@ -122,6 +118,24 @@ static std::vector<std::string> get_arch_list(volk_gnsssdr_func_desc_t desc)
return archlist;
}
template <typename T>
T volk_lexical_cast(const std::string &str)
{
for (unsigned int c_index = 0; c_index < str.size(); ++c_index)
{
if (str.at(c_index) < '0' || str.at(c_index) > '9')
{
throw "not all numbers!";
}
}
T var;
std::istringstream iss;
iss.str(str);
iss >> var;
// deal with any error bits that may have been set on the stream
return var;
}
volk_gnsssdr_type_t volk_gnsssdr_type_from_string(std::string name)
{
volk_gnsssdr_type_t type;
@ -151,7 +165,7 @@ volk_gnsssdr_type_t volk_gnsssdr_type_from_string(std::string name)
throw std::string("no size spec in type ").append(name);
}
//will throw if malformed
int size = boost::lexical_cast<int>(name.substr(0, last_size_pos + 1));
int size = volk_lexical_cast<int>(name.substr(0, last_size_pos + 1));
assert(((size % 8) == 0) && (size <= 64) && (size != 0));
type.size = size / 8; //in bytes
@ -180,21 +194,42 @@ volk_gnsssdr_type_t volk_gnsssdr_type_from_string(std::string name)
return type;
}
std::vector<std::string> split_signature(const std::string &protokernel_signature)
{
std::vector<std::string> signature_tokens;
std::string token;
for (unsigned int loc = 0; loc < protokernel_signature.size(); ++loc)
{
if (protokernel_signature.at(loc) == '_')
{
if (protokernel_signature.substr(loc + 1, 7).compare("gnsssdr") == 0) // jump the "gnsssdr" part of "volk_gnsssdr"
{
loc += 7;
}
else
{
// this is a break
signature_tokens.push_back(token);
token = "";
}
}
else
{
token.push_back(protokernel_signature.at(loc));
}
}
// Get the last one to the end of the string
signature_tokens.push_back(token);
return signature_tokens;
}
static void get_signatures_from_name(std::vector<volk_gnsssdr_type_t> &inputsig,
std::vector<volk_gnsssdr_type_t> &outputsig,
std::string name)
{
boost::char_separator<char> sep("_");
boost::tokenizer<boost::char_separator<char> > tok(name, sep);
std::vector<std::string> toked;
tok.assign(name);
toked.assign(tok.begin(), tok.end());
std::vector<std::string> toked = split_signature(name);
assert(toked[0] == "volk");
toked.erase(toked.begin());
toked.erase(toked.begin());
//ok. we're assuming a string in the form
//(sig)_(multiplier-opt)_..._(name)_(sig)_(multiplier-opt)_..._(alignment)
enum
{
@ -204,8 +239,9 @@ static void get_signatures_from_name(std::vector<volk_gnsssdr_type_t> &inputsig,
} side = SIDE_INPUT;
std::string fn_name;
volk_gnsssdr_type_t type;
BOOST_FOREACH (std::string token, toked)
for (unsigned int token_index = 0; token_index < toked.size(); ++token_index)
{
std::string token = toked[token_index];
try
{
type = volk_gnsssdr_type_from_string(token);
@ -224,7 +260,7 @@ static void get_signatures_from_name(std::vector<volk_gnsssdr_type_t> &inputsig,
assert(inputsig.size() > 0);
else
assert(outputsig.size() > 0);
int multiplier = boost::lexical_cast<int>(token.substr(1, token.size() - 1)); //will throw if invalid ///////////
int multiplier = volk_lexical_cast<int>(token.substr(1, token.size() - 1)); // will throw if invalid
for (int i = 1; i < multiplier; i++)
{
if (side == SIDE_INPUT)
@ -523,7 +559,7 @@ bool run_volk_gnsssdr_tests(volk_gnsssdr_func_desc_t desc,
{
get_signatures_from_name(inputsig, outputsig, name);
}
catch (boost::bad_lexical_cast &error)
catch (std::exception &error)
{
std::cerr << "Error: unable to get function signature from kernel name" << std::endl;
std::cerr << " - " << name << std::endl;
@ -542,8 +578,9 @@ bool run_volk_gnsssdr_tests(volk_gnsssdr_func_desc_t desc,
}
}
std::vector<void *> inbuffs;
BOOST_FOREACH (volk_gnsssdr_type_t sig, inputsig)
for (unsigned int inputsig_index = 0; inputsig_index < inputsig.size(); ++inputsig_index)
{
volk_gnsssdr_type_t sig = inputsig[inputsig_index];
if (!sig.is_scalar) //we don't make buffers for scalars
inbuffs.push_back(mem_pool.get_new(vlen * sig.size * (sig.is_complex ? 2 : 1)));
}
@ -703,6 +740,9 @@ bool run_volk_gnsssdr_tests(volk_gnsssdr_func_desc_t desc,
else
throw "unsupported 3 arg function >1 scalars";
break;
case 4:
run_cast_test4((volk_gnsssdr_fn_4arg)(manual_func), test_data[i], vlen, iter, arch_list[i]);
break;
default:
throw "no function handler for this signature";
break;

View File

@ -31,7 +31,7 @@
void print_qa_xml(std::vector<volk_gnsssdr_test_results_t> results, unsigned int nfails);
int main()
int main(int argc, char* argv[])
{
bool qa_ret_val = 0;
@ -45,47 +45,78 @@ int main()
volk_gnsssdr_test_params_t test_params(def_tol, def_scalar, def_vlen, def_iter,
def_benchmark_mode, def_kernel_regex);
std::vector<volk_gnsssdr_test_case_t> test_cases = init_test_list(test_params);
std::vector<std::string> qa_failures;
std::vector<volk_gnsssdr_test_results_t> results;
// Test every kernel reporting failures when they occur
for (unsigned int ii = 0; ii < test_cases.size(); ++ii)
if (argc > 1)
{
bool qa_result = false;
volk_gnsssdr_test_case_t test_case = test_cases[ii];
try
const size_t len = std::char_traits<char>::length(argv[1]);
if (len == 0 || len > 2046)
{
qa_result = run_volk_gnsssdr_tests(test_case.desc(), test_case.kernel_ptr(), test_case.name(),
test_case.test_parameters(), &results, test_case.puppet_master_name());
std::cerr << "Test name is too long." << std::endl;
return 0;
}
catch (...)
for (unsigned int ii = 0; ii < test_cases.size(); ++ii)
{
// TODO: what exceptions might we need to catch and how do we handle them?
std::cerr << "Exception found on kernel: " << test_case.name() << std::endl;
qa_result = false;
}
if (qa_result)
{
std::cerr << "Failure on " << test_case.name() << std::endl;
qa_failures.push_back(test_case.name());
if (std::string(argv[1]) == test_cases[ii].name())
{
volk_gnsssdr_test_case_t test_case = test_cases[ii];
if (run_volk_gnsssdr_tests(test_case.desc(), test_case.kernel_ptr(),
test_case.name(),
test_case.test_parameters(), &results,
test_case.puppet_master_name()))
{
return 1;
}
else
{
return 0;
}
}
}
std::cerr << "Did not run a test for kernel: " << std::string(argv[1]) << " !" << std::endl;
return 0;
}
// Generate XML results
print_qa_xml(results, qa_failures.size());
// Summarize QA results
std::cerr << "Kernel QA finished: " << qa_failures.size() << " failures out of "
<< test_cases.size() << " tests." << std::endl;
if (qa_failures.size() > 0)
else
{
std::cerr << "The following kernels failed QA:" << std::endl;
for (unsigned int ii = 0; ii < qa_failures.size(); ++ii)
std::vector<std::string> qa_failures;
// Test every kernel reporting failures when they occur
for (unsigned int ii = 0; ii < test_cases.size(); ++ii)
{
std::cerr << " " << qa_failures[ii] << std::endl;
bool qa_result = false;
volk_gnsssdr_test_case_t test_case = test_cases[ii];
try
{
qa_result = run_volk_gnsssdr_tests(test_case.desc(), test_case.kernel_ptr(), test_case.name(),
test_case.test_parameters(), &results, test_case.puppet_master_name());
}
catch (...)
{
// TODO: what exceptions might we need to catch and how do we handle them?
std::cerr << "Exception found on kernel: " << test_case.name() << std::endl;
qa_result = false;
}
if (qa_result)
{
std::cerr << "Failure on " << test_case.name() << std::endl;
qa_failures.push_back(test_case.name());
}
}
// Generate XML results
print_qa_xml(results, qa_failures.size());
// Summarize QA results
std::cerr << "Kernel QA finished: " << qa_failures.size() << " failures out of "
<< test_cases.size() << " tests." << std::endl;
if (qa_failures.size() > 0)
{
std::cerr << "The following kernels failed QA:" << std::endl;
for (unsigned int ii = 0; ii < qa_failures.size(); ++ii)
{
std::cerr << " " << qa_failures[ii] << std::endl;
}
qa_ret_val = 1;
}
qa_ret_val = 1;
}
return qa_ret_val;
@ -128,7 +159,6 @@ void print_qa_xml(std::vector<volk_gnsssdr_test_results_t> results, unsigned int
qa_file << " </testsuite>" << std::endl;
}
qa_file << "</testsuites>" << std::endl;
qa_file.close();
}

View File

@ -35,7 +35,7 @@ typedef struct volk_gnsssdr_func_desc
const char **impl_names;
const int *impl_deps;
const bool *impl_alignment;
const size_t n_impls;
size_t n_impls;
} volk_gnsssdr_func_desc_t;
//! Prints a list of machines available
@ -68,12 +68,12 @@ VOLK_API size_t volk_gnsssdr_get_alignment(void);
*/
VOLK_API bool volk_gnsssdr_is_aligned(const void *ptr);
// clang-format off
%for kern in kernels:
//! A function pointer to the dispatcher implementation
extern VOLK_API ${kern.pname} ${kern.name};
// clang-format off
//! A function pointer to the fastest aligned implementation
extern VOLK_API ${kern.pname} ${kern.name}_a;
@ -86,9 +86,7 @@ extern VOLK_API void ${kern.name}_manual(${kern.arglist_full}, const char* impl_
//! Get description parameters for this kernel
extern VOLK_API volk_gnsssdr_func_desc_t ${kern.name}_get_func_desc(void);
%endfor
// clang-format off
__VOLK_DECL_END
// clang-format on
#endif /*INCLUDED_VOLK_GNSSSDR_RUNTIME*/

View File

@ -32,40 +32,27 @@
#include "hybrid_observables.h"
#include "configuration_interface.h"
#include "Galileo_E1.h"
#include "GPS_L1_CA.h"
#include <glog/logging.h>
using google::LogMessage;
HybridObservables::HybridObservables(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams) : role_(role),
in_streams_(in_streams),
out_streams_(out_streams)
std::string role, unsigned int in_streams, unsigned int out_streams) :
role_(role), in_streams_(in_streams), out_streams_(out_streams)
{
std::string default_dump_filename = "./observables.dat";
DLOG(INFO) << "role " << role;
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
unsigned int default_depth = 0;
if (GPS_L1_CA_HISTORY_DEEP == GALILEO_E1_HISTORY_DEEP)
{
default_depth = GPS_L1_CA_HISTORY_DEEP;
}
else
{
default_depth = 500;
}
unsigned int history_deep = configuration->property(role + ".history_depth", default_depth);
observables_ = hybrid_make_observables_cc(in_streams_, dump_, dump_filename_, history_deep);
DLOG(INFO) << "pseudorange(" << observables_->unique_id() << ")";
observables_ = hybrid_make_observables_cc(in_streams_, out_streams_, dump_, dump_filename_);
DLOG(INFO) << "Observables block ID (" << observables_->unique_id() << ")";
}
HybridObservables::~HybridObservables() {}
HybridObservables::~HybridObservables()
{}
void HybridObservables::connect(gr::top_block_sptr top_block)

View File

@ -1,11 +1,12 @@
/*!
* \file hybrid_observables_cc.cc
* \brief Implementation of the pseudorange computation block for Galileo E1
* \brief Implementation of the observables computation block
* \author Javier Arribas 2017. jarribas(at)cttc.es
* \author Antonio Ramos 2018. antonio.ramos(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
@ -29,50 +30,52 @@
*/
#include "hybrid_observables_cc.h"
#include "Galileo_E1.h"
#include "display.h"
#include "GPS_L1_CA.h"
#include <armadillo>
#include <glog/logging.h>
#include <gnuradio/io_signature.h>
#include <gnuradio/block_detail.h>
#include <gnuradio/buffer.h>
#include <matio.h>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <utility>
#include <limits>
using google::LogMessage;
hybrid_observables_cc_sptr hybrid_make_observables_cc(unsigned int nchannels, bool dump, std::string dump_filename, unsigned int deep_history)
hybrid_observables_cc_sptr hybrid_make_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, std::string dump_filename)
{
return hybrid_observables_cc_sptr(new hybrid_observables_cc(nchannels, dump, dump_filename, deep_history));
return hybrid_observables_cc_sptr(new hybrid_observables_cc(nchannels_in, nchannels_out, dump, dump_filename));
}
hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels, bool dump, std::string dump_filename, unsigned int deep_history) : gr::block("hybrid_observables_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)),
gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)))
hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels_in,
unsigned int nchannels_out,
bool dump,
std::string dump_filename) : gr::block("hybrid_observables_cc",
gr::io_signature::make(nchannels_in, nchannels_in, sizeof(Gnss_Synchro)),
gr::io_signature::make(nchannels_out, nchannels_out, sizeof(Gnss_Synchro)))
{
// initialize internal vars
d_dump = dump;
d_nchannels = nchannels;
d_nchannels = nchannels_out;
d_dump_filename = dump_filename;
history_deep = deep_history;
T_rx_s = 0.0;
T_rx_step_s = 1e-3; // todo: move to gnss-sdr config
T_rx_step_s = 0.001; // 1 ms
max_delta = 0.15; // 150 ms
valid_channels.resize(d_nchannels, false);
d_num_valid_channels = 0;
for (unsigned int i = 0; i < d_nchannels; i++)
{
d_gnss_synchro_history_queue.push_back(std::deque<Gnss_Synchro>());
d_gnss_synchro_history.push_back(std::deque<Gnss_Synchro>());
}
// ############# ENABLE DATA FILE LOG #################
if (d_dump == true)
if (d_dump)
{
if (d_dump_file.is_open() == false)
if (!d_dump_file.is_open())
{
try
{
@ -83,6 +86,7 @@ hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels, bool dump,
catch (const std::ifstream::failure &e)
{
LOG(WARNING) << "Exception opening observables dump file " << e.what();
d_dump = false;
}
}
}
@ -91,7 +95,7 @@ hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels, bool dump,
hybrid_observables_cc::~hybrid_observables_cc()
{
if (d_dump_file.is_open() == true)
if (d_dump_file.is_open())
{
try
{
@ -102,10 +106,10 @@ hybrid_observables_cc::~hybrid_observables_cc()
LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what();
}
}
if (d_dump == true)
if (d_dump)
{
std::cout << "Writing observables .mat files ...";
hybrid_observables_cc::save_matfile();
save_matfile();
std::cout << " done." << std::endl;
}
}
@ -230,7 +234,10 @@ int hybrid_observables_cc::save_matfile()
mat_t *matfp;
matvar_t *matvar;
std::string filename = d_dump_filename;
filename.erase(filename.length() - 4, 4);
if (filename.size() > 4)
{
filename.erase(filename.end() - 4, filename.end());
}
filename.append(".mat");
matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73);
if (reinterpret_cast<long *>(matfp) != NULL)
@ -295,303 +302,294 @@ int hybrid_observables_cc::save_matfile()
}
bool Hybrid_pairCompare_gnss_synchro_sample_counter(const std::pair<int, Gnss_Synchro> &a, const std::pair<int, Gnss_Synchro> &b)
bool hybrid_observables_cc::interpolate_data(Gnss_Synchro &out, std::deque<Gnss_Synchro> &data, const double &ti)
{
return (a.second.Tracking_sample_counter) < (b.second.Tracking_sample_counter);
if ((ti < data.front().RX_time) or (ti > data.back().RX_time))
{
return false;
}
std::deque<Gnss_Synchro>::iterator it;
arma::vec t = arma::vec(data.size());
arma::vec dop = t;
arma::vec cph = t;
arma::vec tow = t;
arma::vec tiv = arma::vec(1);
arma::vec result;
tiv(0) = ti;
unsigned int aux = 0;
for (it = data.begin(); it != data.end(); it++)
{
t(aux) = it->RX_time;
dop(aux) = it->Carrier_Doppler_hz;
cph(aux) = it->Carrier_phase_rads;
tow(aux) = it->TOW_at_current_symbol_s;
aux++;
}
arma::interp1(t, dop, tiv, result);
out.Carrier_Doppler_hz = result(0);
arma::interp1(t, cph, tiv, result);
out.Carrier_phase_rads = result(0);
arma::interp1(t, tow, tiv, result);
out.TOW_at_current_symbol_s = result(0);
return result.is_finite();
}
bool Hybrid_valueCompare_gnss_synchro_sample_counter(const Gnss_Synchro &a, unsigned long int b)
double hybrid_observables_cc::compute_T_rx_s(const Gnss_Synchro &a)
{
return (a.Tracking_sample_counter) < (b);
if (a.Flag_valid_word)
{
return ((static_cast<double>(a.Tracking_sample_counter) + a.Code_phase_samples) / static_cast<double>(a.fs));
}
else
{
return 0.0;
}
}
bool Hybrid_valueCompare_gnss_synchro_receiver_time(const Gnss_Synchro &a, double b)
void hybrid_observables_cc::forecast(int noutput_items __attribute__((unused)),
gr_vector_int &ninput_items_required)
{
return ((static_cast<double>(a.Tracking_sample_counter) + static_cast<double>(a.Code_phase_samples)) / static_cast<double>(a.fs)) < (b);
}
bool Hybrid_pairCompare_gnss_synchro_d_TOW(const std::pair<int, Gnss_Synchro> &a, const std::pair<int, Gnss_Synchro> &b)
{
return (a.second.TOW_at_current_symbol_s) < (b.second.TOW_at_current_symbol_s);
}
bool Hybrid_valueCompare_gnss_synchro_d_TOW(const Gnss_Synchro &a, double b)
{
return (a.TOW_at_current_symbol_s) < (b);
}
void hybrid_observables_cc::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required)
{
bool zero_samples = true;
for (unsigned int i = 0; i < d_nchannels; i++)
{
int items = detail()->input(i)->items_available();
if (items > 0) zero_samples = false;
ninput_items_required[i] = items; // set the required available samples in each call
ninput_items_required[i] = 0;
}
ninput_items_required[d_nchannels] = 1;
}
if (zero_samples == true)
void hybrid_observables_cc::clean_history(std::deque<Gnss_Synchro> &data)
{
while (data.size() > 0)
{
for (unsigned int i = 0; i < d_nchannels; i++)
if ((T_rx_s - data.front().RX_time) > max_delta)
{
ninput_items_required[i] = 1; // set the required available samples in each call
data.pop_front();
}
else
{
return;
}
}
}
int hybrid_observables_cc::general_work(int noutput_items,
gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items,
void hybrid_observables_cc::correct_TOW_and_compute_prange(std::vector<Gnss_Synchro> &data)
{
std::vector<Gnss_Synchro>::iterator it;
/////////////////////// DEBUG //////////////////////////
// Logs if there is a pseudorange difference between
// signals of the same satellite higher than a threshold
////////////////////////////////////////////////////////
#ifndef NDEBUG
std::vector<Gnss_Synchro>::iterator it2;
double thr_ = 250.0 / SPEED_OF_LIGHT; // Maximum pseudorange difference = 250 meters
for (it = data.begin(); it != (data.end() - 1); it++)
{
for (it2 = it + 1; it2 != data.end(); it2++)
{
if (it->PRN == it2->PRN and it->System == it2->System)
{
double tow_dif_ = std::fabs(it->TOW_at_current_symbol_s - it2->TOW_at_current_symbol_s);
if (tow_dif_ > thr_)
{
DLOG(INFO) << "System " << it->System << ". Signals " << it->Signal << " and " << it2->Signal
<< ". TOW difference in PRN " << it->PRN
<< " = " << tow_dif_ * 1e3 << "[ms]. Equivalent to " << tow_dif_ * SPEED_OF_LIGHT
<< " meters in pseudorange";
std::cout << TEXT_RED << "System " << it->System << ". Signals " << it->Signal << " and " << it2->Signal
<< ". TOW difference in PRN " << it->PRN
<< " = " << tow_dif_ * 1e3 << "[ms]. Equivalent to " << tow_dif_ * SPEED_OF_LIGHT
<< " meters in pseudorange" << TEXT_RESET << std::endl;
}
}
}
}
#endif
///////////////////////////////////////////////////////////
double TOW_ref = std::numeric_limits<double>::lowest();
for (it = data.begin(); it != data.end(); it++)
{
if (it->TOW_at_current_symbol_s > TOW_ref)
{
TOW_ref = it->TOW_at_current_symbol_s;
}
}
for (it = data.begin(); it != data.end(); it++)
{
double traveltime_s = TOW_ref - it->TOW_at_current_symbol_s + GPS_STARTOFFSET_ms / 1000.0;
it->RX_time = TOW_ref + GPS_STARTOFFSET_ms / 1000.0;
it->Pseudorange_m = traveltime_s * SPEED_OF_LIGHT;
}
}
int hybrid_observables_cc::general_work(int noutput_items __attribute__((unused)),
gr_vector_int &ninput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const Gnss_Synchro **in = reinterpret_cast<const Gnss_Synchro **>(&input_items[0]); // Get the input buffer pointer
Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); // Get the output buffer pointer
int n_outputs = 0;
int n_consume[d_nchannels];
double past_history_s = 100e-3;
const Gnss_Synchro **in = reinterpret_cast<const Gnss_Synchro **>(&input_items[0]);
Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]);
Gnss_Synchro current_gnss_synchro[d_nchannels];
Gnss_Synchro aux = Gnss_Synchro();
for (unsigned int i = 0; i < d_nchannels; i++)
unsigned int i;
int total_input_items = 0;
for (i = 0; i < d_nchannels; i++)
{
current_gnss_synchro[i] = aux;
total_input_items += ninput_items[i];
}
/*
* 1. Read the GNSS SYNCHRO objects from available channels.
* Multi-rate GNURADIO Block. Read how many input items are avaliable in each channel
* Record all synchronization data into queues
*/
for (unsigned int i = 0; i < d_nchannels; i++)
consume(d_nchannels, 1);
T_rx_s += T_rx_step_s;
//////////////////////////////////////////////////////////////////////////
if ((total_input_items == 0) and (d_num_valid_channels == 0))
{
n_consume[i] = ninput_items[i]; // full throttle
for (int j = 0; j < n_consume[i]; j++)
{
d_gnss_synchro_history_queue[i].push_back(in[i][j]);
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
bool channel_history_ok;
do
std::vector<std::deque<Gnss_Synchro>>::iterator it;
if (total_input_items > 0)
{
channel_history_ok = true;
for (unsigned int i = 0; i < d_nchannels; i++)
i = 0;
for (it = d_gnss_synchro_history.begin(); it != d_gnss_synchro_history.end(); it++)
{
if (d_gnss_synchro_history_queue[i].size() < history_deep)
if (ninput_items[i] > 0)
{
channel_history_ok = false;
}
}
if (channel_history_ok == true)
{
std::map<int, Gnss_Synchro>::const_iterator gnss_synchro_map_iter;
std::deque<Gnss_Synchro>::const_iterator gnss_synchro_deque_iter;
// 1. If the RX time is not set, set the Rx time
if (T_rx_s == 0)
{
// 0. Read a gnss_synchro snapshot from the queue and store it in a map
std::map<int, Gnss_Synchro> gnss_synchro_map;
for (unsigned int i = 0; i < d_nchannels; i++)
// Add the new Gnss_Synchros to their corresponding deque
for (int aux = 0; aux < ninput_items[i]; aux++)
{
gnss_synchro_map.insert(std::pair<int, Gnss_Synchro>(d_gnss_synchro_history_queue[i].front().Channel_ID,
d_gnss_synchro_history_queue[i].front()));
}
gnss_synchro_map_iter = min_element(gnss_synchro_map.cbegin(),
gnss_synchro_map.cend(),
Hybrid_pairCompare_gnss_synchro_sample_counter);
T_rx_s = static_cast<double>(gnss_synchro_map_iter->second.Tracking_sample_counter) / static_cast<double>(gnss_synchro_map_iter->second.fs);
T_rx_s = floor(T_rx_s * 1000.0) / 1000.0; // truncate to ms
T_rx_s += past_history_s; // increase T_rx to have a minimum past history to interpolate
}
// 2. Realign RX time in all valid channels
std::map<int, Gnss_Synchro> realigned_gnss_synchro_map; // container for the aligned set of observables for the selected T_rx
std::map<int, Gnss_Synchro> adjacent_gnss_synchro_map; // container for the previous observable values to interpolate
// shift channels history to match the reference TOW
for (unsigned int i = 0; i < d_nchannels; i++)
{
gnss_synchro_deque_iter = std::lower_bound(d_gnss_synchro_history_queue[i].cbegin(),
d_gnss_synchro_history_queue[i].cend(),
T_rx_s,
Hybrid_valueCompare_gnss_synchro_receiver_time);
if (gnss_synchro_deque_iter != d_gnss_synchro_history_queue[i].cend())
{
if (gnss_synchro_deque_iter->Flag_valid_word == true)
if (in[i][aux].Flag_valid_word)
{
double T_rx_channel = static_cast<double>(gnss_synchro_deque_iter->Tracking_sample_counter) / static_cast<double>(gnss_synchro_deque_iter->fs);
double delta_T_rx_s = T_rx_channel - T_rx_s;
// check that T_rx difference is less than a threshold (the correlation interval)
if (delta_T_rx_s * 1000.0 < static_cast<double>(gnss_synchro_deque_iter->correlation_length_ms))
it->push_back(in[i][aux]);
it->back().RX_time = compute_T_rx_s(in[i][aux]);
// Check if the last Gnss_Synchro comes from the same satellite as the previous ones
if (it->size() > 1)
{
// record the word structure in a map for pseudorange computation
// save the previous observable
int distance = std::distance(d_gnss_synchro_history_queue[i].cbegin(), gnss_synchro_deque_iter);
if (distance > 0)
if (it->front().PRN != it->back().PRN)
{
if (d_gnss_synchro_history_queue[i].at(distance - 1).Flag_valid_word)
{
double T_rx_channel_prev = static_cast<double>(d_gnss_synchro_history_queue[i].at(distance - 1).Tracking_sample_counter) / static_cast<double>(gnss_synchro_deque_iter->fs);
double delta_T_rx_s_prev = T_rx_channel_prev - T_rx_s;
if (fabs(delta_T_rx_s_prev) < fabs(delta_T_rx_s))
{
realigned_gnss_synchro_map.insert(std::pair<int, Gnss_Synchro>(d_gnss_synchro_history_queue[i].at(distance - 1).Channel_ID,
d_gnss_synchro_history_queue[i].at(distance - 1)));
adjacent_gnss_synchro_map.insert(std::pair<int, Gnss_Synchro>(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter));
}
else
{
realigned_gnss_synchro_map.insert(std::pair<int, Gnss_Synchro>(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter));
adjacent_gnss_synchro_map.insert(std::pair<int, Gnss_Synchro>(d_gnss_synchro_history_queue[i].at(distance - 1).Channel_ID,
d_gnss_synchro_history_queue[i].at(distance - 1)));
}
}
}
else
{
realigned_gnss_synchro_map.insert(std::pair<int, Gnss_Synchro>(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter));
it->clear();
}
}
}
}
consume(i, ninput_items[i]);
}
i++;
}
}
for (i = 0; i < d_nchannels; i++)
{
if (d_gnss_synchro_history.at(i).size() > 2)
{
valid_channels[i] = true;
}
else
{
valid_channels[i] = false;
}
}
d_num_valid_channels = valid_channels.count();
// Check if there is any valid channel after reading the new incoming Gnss_Synchro data
if (d_num_valid_channels == 0)
{
return 0;
}
if (!realigned_gnss_synchro_map.empty())
for (i = 0; i < d_nchannels; i++) //Discard observables with T_rx higher than the threshold
{
if (valid_channels[i])
{
clean_history(d_gnss_synchro_history.at(i));
if (d_gnss_synchro_history.at(i).size() < 2)
{
/*
* 2.1 Use CURRENT set of measurements and find the nearest satellite
* common RX time algorithm
*/
// what is the most recent symbol TOW in the current set? -> this will be the reference symbol
gnss_synchro_map_iter = max_element(realigned_gnss_synchro_map.cbegin(),
realigned_gnss_synchro_map.cend(),
Hybrid_pairCompare_gnss_synchro_d_TOW);
double ref_fs_hz = static_cast<double>(gnss_synchro_map_iter->second.fs);
// compute interpolated TOW value at T_rx_s
int ref_channel_key = gnss_synchro_map_iter->second.Channel_ID;
Gnss_Synchro adj_obs;
adj_obs = adjacent_gnss_synchro_map.at(ref_channel_key);
double ref_adj_T_rx_s = static_cast<double>(adj_obs.Tracking_sample_counter) / ref_fs_hz + adj_obs.Code_phase_samples / ref_fs_hz;
double d_TOW_reference = gnss_synchro_map_iter->second.TOW_at_current_symbol_s;
double d_ref_T_rx_s = static_cast<double>(gnss_synchro_map_iter->second.Tracking_sample_counter) / ref_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / ref_fs_hz;
double selected_T_rx_s = T_rx_s;
// two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1)
double ref_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s +
(selected_T_rx_s - ref_adj_T_rx_s) * (d_TOW_reference - adj_obs.TOW_at_current_symbol_s) / (d_ref_T_rx_s - ref_adj_T_rx_s);
// Now compute RX time differences due to the PRN alignment in the correlators
double traveltime_ms;
double pseudorange_m;
double channel_T_rx_s;
double channel_fs_hz;
double channel_TOW_s;
for (gnss_synchro_map_iter = realigned_gnss_synchro_map.cbegin(); gnss_synchro_map_iter != realigned_gnss_synchro_map.cend(); gnss_synchro_map_iter++)
{
channel_fs_hz = static_cast<double>(gnss_synchro_map_iter->second.fs);
channel_TOW_s = gnss_synchro_map_iter->second.TOW_at_current_symbol_s;
channel_T_rx_s = static_cast<double>(gnss_synchro_map_iter->second.Tracking_sample_counter) / channel_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / channel_fs_hz;
// compute interpolated observation values
// two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1)
// TOW at the selected receiver time T_rx_s
int element_key = gnss_synchro_map_iter->second.Channel_ID;
try
{
adj_obs = adjacent_gnss_synchro_map.at(element_key);
}
catch (const std::exception &ex)
{
continue;
}
double adj_T_rx_s = static_cast<double>(adj_obs.Tracking_sample_counter) / channel_fs_hz + adj_obs.Code_phase_samples / channel_fs_hz;
double channel_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + (selected_T_rx_s - adj_T_rx_s) * (channel_TOW_s - adj_obs.TOW_at_current_symbol_s) / (channel_T_rx_s - adj_T_rx_s);
// Doppler and Accumulated carrier phase
double Carrier_phase_lin_rads = adj_obs.Carrier_phase_rads + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_phase_rads - adj_obs.Carrier_phase_rads) / (channel_T_rx_s - adj_T_rx_s);
double Carrier_Doppler_lin_hz = adj_obs.Carrier_Doppler_hz + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_Doppler_hz - adj_obs.Carrier_Doppler_hz) / (channel_T_rx_s - adj_T_rx_s);
// compute the pseudorange (no rx time offset correction)
traveltime_ms = (ref_TOW_at_T_rx_s - channel_TOW_at_T_rx_s) * 1000.0 + GPS_STARTOFFSET_ms;
// convert to meters
pseudorange_m = traveltime_ms * GPS_C_m_ms; // [m]
// update the pseudorange object
current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID] = gnss_synchro_map_iter->second;
current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Pseudorange_m = pseudorange_m;
current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Flag_valid_pseudorange = true;
// Save the estimated RX time (no RX clock offset correction yet!)
current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].RX_time = ref_TOW_at_T_rx_s + GPS_STARTOFFSET_ms / 1000.0;
current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_phase_rads = Carrier_phase_lin_rads;
current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_Doppler_hz = Carrier_Doppler_lin_hz;
}
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 = current_gnss_synchro[i].RX_time;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = current_gnss_synchro[i].TOW_at_current_symbol_s;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = current_gnss_synchro[i].Carrier_Doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = current_gnss_synchro[i].Carrier_phase_rads / GPS_TWO_PI;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = current_gnss_synchro[i].Pseudorange_m;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = current_gnss_synchro[i].PRN;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = static_cast<double>(current_gnss_synchro[i].Flag_valid_pseudorange);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
}
}
catch (const std::ifstream::failure &e)
{
LOG(WARNING) << "Exception writing observables dump file " << e.what();
}
}
for (unsigned int i = 0; i < d_nchannels; i++)
{
out[i][n_outputs] = current_gnss_synchro[i];
}
n_outputs++;
}
// Move RX time
T_rx_s = T_rx_s + T_rx_step_s;
// pop old elements from queue
for (unsigned int i = 0; i < d_nchannels; i++)
{
while (static_cast<double>(d_gnss_synchro_history_queue[i].front().Tracking_sample_counter) / static_cast<double>(d_gnss_synchro_history_queue[i].front().fs) < (T_rx_s - past_history_s))
{
d_gnss_synchro_history_queue[i].pop_front();
}
valid_channels[i] = false;
}
}
}
while (channel_history_ok == true && noutput_items > n_outputs);
// Multi-rate consume!
for (unsigned int i = 0; i < d_nchannels; i++)
// Check if there is any valid channel after computing the time distance between the Gnss_Synchro data and the receiver time
d_num_valid_channels = valid_channels.count();
double T_rx_s_out = T_rx_s - (max_delta / 2.0);
if ((d_num_valid_channels == 0) or (T_rx_s_out < 0.0))
{
consume(i, n_consume[i]); // which input, how many items
return 0;
}
return n_outputs;
std::vector<Gnss_Synchro> epoch_data;
i = 0;
for (it = d_gnss_synchro_history.begin(); it != d_gnss_synchro_history.end(); it++)
{
if (valid_channels[i])
{
Gnss_Synchro interpolated_gnss_synchro = it->back();
if (interpolate_data(interpolated_gnss_synchro, *it, T_rx_s_out))
{
epoch_data.push_back(interpolated_gnss_synchro);
}
else
{
valid_channels[i] = false;
}
}
i++;
}
d_num_valid_channels = valid_channels.count();
if (d_num_valid_channels == 0)
{
return 0;
}
correct_TOW_and_compute_prange(epoch_data);
std::vector<Gnss_Synchro>::iterator it2 = epoch_data.begin();
for (i = 0; i < d_nchannels; i++)
{
if (valid_channels[i])
{
out[i][0] = (*it2);
out[i][0].Flag_valid_pseudorange = true;
it2++;
}
else
{
out[i][0] = Gnss_Synchro();
out[i][0].Flag_valid_pseudorange = false;
}
}
if (d_dump)
{
// MULTIPLEXED FILE RECORDING - Record results to file
try
{
double tmp_double;
for (i = 0; i < d_nchannels; i++)
{
tmp_double = out[i][0].RX_time;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = out[i][0].TOW_at_current_symbol_s;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = out[i][0].Carrier_Doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = out[i][0].Carrier_phase_rads / GPS_TWO_PI;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = out[i][0].Pseudorange_m;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = static_cast<double>(out[i][0].PRN);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = static_cast<double>(out[i][0].Flag_valid_pseudorange);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
}
}
catch (const std::ifstream::failure &e)
{
LOG(WARNING) << "Exception writing observables dump file " << e.what();
d_dump = false;
}
}
return 1;
}

View File

@ -1,12 +1,13 @@
/*!
* \file hybrid_observables_cc.h
* \brief Interface of the observables computation block for Galileo E1
* \brief Interface of the observables computation block
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
* \author Javier Arribas 2013. jarribas(at)cttc.es
* \author Antonio Ramos 2018. antonio.ramos(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
@ -35,8 +36,11 @@
#include "gnss_synchro.h"
#include <gnuradio/block.h>
#include <boost/dynamic_bitset.hpp>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
class hybrid_observables_cc;
@ -44,36 +48,40 @@ class hybrid_observables_cc;
typedef boost::shared_ptr<hybrid_observables_cc> hybrid_observables_cc_sptr;
hybrid_observables_cc_sptr
hybrid_make_observables_cc(unsigned int n_channels, bool dump, std::string dump_filename, unsigned int deep_history);
hybrid_make_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, std::string dump_filename);
/*!
* \brief This class implements a block that computes Galileo observables
* \brief This class implements a block that computes observables
*/
class hybrid_observables_cc : public gr::block
{
public:
~hybrid_observables_cc();
int general_work(int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
void forecast(int noutput_items, gr_vector_int &ninput_items_required);
int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_void_star& output_items);
void forecast(int noutput_items, gr_vector_int& ninput_items_required);
private:
friend hybrid_observables_cc_sptr
hybrid_make_observables_cc(unsigned int nchannels, bool dump, std::string dump_filename, unsigned int deep_history);
hybrid_observables_cc(unsigned int nchannels, bool dump, std::string dump_filename, unsigned int deep_history);
hybrid_make_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, std::string dump_filename);
hybrid_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, std::string dump_filename);
void clean_history(std::deque<Gnss_Synchro>& data);
double compute_T_rx_s(const Gnss_Synchro& a);
bool interpolate_data(Gnss_Synchro& out, std::deque<Gnss_Synchro>& data, const double& ti);
void correct_TOW_and_compute_prange(std::vector<Gnss_Synchro>& data);
int save_matfile();
//Tracking observable history
std::vector<std::deque<Gnss_Synchro>> d_gnss_synchro_history_queue;
std::vector<std::deque<Gnss_Synchro>> d_gnss_synchro_history;
boost::dynamic_bitset<> valid_channels;
double T_rx_s;
double T_rx_step_s;
double max_delta;
bool d_dump;
unsigned int d_nchannels;
unsigned int history_deep;
unsigned int d_num_valid_channels;
std::string d_dump_filename;
std::ofstream d_dump_file;
int save_matfile();
};
#endif

View File

@ -32,9 +32,9 @@ include_directories(
)
if(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.13" )
if(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.15" )
add_definitions( -DGR_GREATER_38=1 )
endif(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.13" )
endif(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.15" )
file(GLOB RESAMPLER_ADAPTER_HEADERS "*.h")

View File

@ -35,7 +35,7 @@
#include "Galileo_E1.h"
#include "GPS_L1_CA.h"
#include "Galileo_E5a.h"
#include "GLONASS_L1_CA.h"
#include "GLONASS_L1_L2_CA.h"
#include <glog/logging.h>
@ -100,7 +100,14 @@ SignalGenerator::SignalGenerator(ConfigurationInterface* configuration,
}
else if (std::find(system.begin(), system.end(), "R") != system.end())
{
vector_length = round((float)fs_in / (GLONASS_L1_CA_CODE_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS));
if (signal1[0].at(0) == '1')
{
vector_length = round((float)fs_in / (GLONASS_L1_CA_CODE_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS));
}
else
{
vector_length = round((float)fs_in / (GLONASS_L2_CA_CODE_RATE_HZ / GLONASS_L2_CA_CODE_LENGTH_CHIPS));
}
}
if (item_type_.compare("gr_complex") == 0)

View File

@ -36,11 +36,12 @@
#include "Galileo_E1.h"
#include "Galileo_E5a.h"
#include "GPS_L1_CA.h"
#include "GLONASS_L1_CA.h"
#include "GLONASS_L1_L2_CA.h"
#include <gnuradio/io_signature.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <fstream>
/*
* Create a new instance of signal_generator_c and return
* a boost shared_ptr. This is effectively the public constructor.

View File

@ -32,7 +32,9 @@
#include "fmcomms2_signal_source.h"
#include "configuration_interface.h"
#include "gnss_sdr_valve.h"
#include "ad9361_manager.h"
#include "GPS_L1_CA.h"
#include "GPS_L2C.h"
#include <glog/logging.h>
#include <iostream>
@ -55,6 +57,7 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration
quadrature_ = configuration->property(role + ".quadrature", true);
rf_dc_ = configuration->property(role + ".rf_dc", true);
bb_dc_ = configuration->property(role + ".bb_dc", true);
RF_channels_ = configuration->property(role + ".RF_channels", 1);
gain_mode_rx1_ = configuration->property(role + ".gain_mode_rx1", std::string("manual"));
gain_mode_rx2_ = configuration->property(role + ".gain_mode_rx2", std::string("manual"));
rf_gain_rx1_ = configuration->property(role + ".gain_rx1", 64.0);
@ -67,6 +70,14 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file);
//AD9361 Local Oscillator generation for dual band operation
enable_dds_lo_ = configuration->property(role + ".enable_dds_lo", false);
freq_rf_tx_hz_ = configuration->property(role + ".freq_rf_tx_hz", GPS_L1_FREQ_HZ - GPS_L2_FREQ_HZ - 1000);
freq_dds_tx_hz_ = configuration->property(role + ".freq_dds_tx_hz", 1000);
scale_dds_dbfs_ = configuration->property(role + ".scale_dds_dbfs", 0.0);
phase_dds_deg_ = configuration->property(role + ".phase_dds_deg", 0.0);
tx_attenuation_db_ = configuration->property(role + ".tx_attenuation_db", 0.0);
item_size_ = sizeof(gr_complex);
std::cout << "device address: " << uri_ << std::endl;
@ -75,15 +86,73 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration
if (item_type_.compare("gr_complex") == 0)
{
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make(
uri_.c_str(), freq_, sample_rate_,
bandwidth_,
rx1_en_, rx2_en_,
buffer_size_, quadrature_, rf_dc_,
bb_dc_, gain_mode_rx1_.c_str(), rf_gain_rx1_,
gain_mode_rx2_.c_str(), rf_gain_rx2_,
rf_port_select_.c_str(), filter_file_.c_str(),
filter_auto_);
if (RF_channels_ == 1)
{
if (rx1_en_ and rx2_en_)
{
LOG(FATAL) << "Configuration error: both rx1 and rx2 are enabled but RF_channels=1 !";
}
else
{
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make(
uri_.c_str(), freq_, sample_rate_,
bandwidth_,
rx1_en_, rx2_en_,
buffer_size_, quadrature_, rf_dc_,
bb_dc_, gain_mode_rx1_.c_str(), rf_gain_rx1_,
gain_mode_rx2_.c_str(), rf_gain_rx2_,
rf_port_select_.c_str(), filter_file_.c_str(),
filter_auto_);
//configure LO
if (enable_dds_lo_ == true)
{
std::cout << "Enabling Local Oscillator generator in FMCOMMS2\n";
config_ad9361_lo_remote(uri_,
bandwidth_,
sample_rate_,
freq_rf_tx_hz_,
tx_attenuation_db_,
freq_dds_tx_hz_,
scale_dds_dbfs_);
}
}
}
else if (RF_channels_ == 2)
{
if (!(rx1_en_ and rx2_en_))
{
LOG(FATAL) << "Configuration error: RF_channels=2 but are not enabled both receivers in FMCOMMS2 !";
}
else
{
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make(
uri_.c_str(), freq_, sample_rate_,
bandwidth_,
rx1_en_, rx2_en_,
buffer_size_, quadrature_, rf_dc_,
bb_dc_, gain_mode_rx1_.c_str(), rf_gain_rx1_,
gain_mode_rx2_.c_str(), rf_gain_rx2_,
rf_port_select_.c_str(), filter_file_.c_str(),
filter_auto_);
//configure LO
if (enable_dds_lo_ == true)
{
std::cout << "Enabling Local Oscillator generator in FMCOMMS2\n";
config_ad9361_lo_remote(uri_,
bandwidth_,
sample_rate_,
freq_rf_tx_hz_,
tx_attenuation_db_,
freq_dds_tx_hz_,
scale_dds_dbfs_);
}
}
}
else
{
LOG(FATAL) << "Configuration error: Unsupported number of RF_channels !";
}
}
else
{
@ -108,6 +177,10 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration
Fmcomms2SignalSource::~Fmcomms2SignalSource()
{
if (enable_dds_lo_ == true)
{
ad9361_disable_lo_remote(uri_);
}
}

View File

@ -88,6 +88,7 @@ private:
bool quadrature_;
bool rf_dc_;
bool bb_dc_;
int RF_channels_;
std::string gain_mode_rx1_;
std::string gain_mode_rx2_;
double rf_gain_rx1_;
@ -96,6 +97,14 @@ private:
std::string filter_file_;
bool filter_auto_;
//DDS configuration for LO generation for external mixer
bool enable_dds_lo_;
unsigned long freq_rf_tx_hz_;
unsigned long freq_dds_tx_hz_;
double scale_dds_dbfs_;
double phase_dds_deg_;
double tx_attenuation_db_;
unsigned int in_stream_;
unsigned int out_stream_;

View File

@ -55,7 +55,7 @@ RtlTcpSignalSource::RtlTcpSignalSource(ConfigurationInterface* configuration,
dump_filename_ = configuration->property(role + ".dump_filename",
default_dump_file);
// rtl_tcp PARAMTERS
// rtl_tcp PARAMETERS
std::string default_address = "127.0.0.1";
short default_port = 1234;
AGC_enabled_ = configuration->property(role + ".AGC_enabled", true);

View File

@ -121,7 +121,7 @@ unpack_2bit_samples::unpack_2bit_samples(bool big_endian_bytes,
bool big_endian_system = systemIsBigEndian();
// Only swap the item bytes if the item size > 1 byte and the system
// endianess is not the same as the item endianness:
// endianness is not the same as the item endianness:
swap_endian_items_ = (item_size_ > 1) &&
(big_endian_system != big_endian_items);

File diff suppressed because it is too large Load Diff

View File

@ -30,8 +30,8 @@
* -------------------------------------------------------------------------
*/
#ifndef __AD9361_MANAGER__
#define __AD9361_MANAGER__
#ifndef GNSS_SDR_AD9361_MANAGER_H
#define GNSS_SDR_AD9361_MANAGER_H
#include <string>
@ -42,31 +42,36 @@
#endif
/* RX is input, TX is output */
enum iodev { RX, TX };
enum iodev
{
RX,
TX
};
/* common RX and TX streaming params */
struct stream_cfg {
long long bw_hz; // Analog banwidth in Hz
long long fs_hz; // Baseband sample rate in Hz
long long lo_hz; // Local oscillator frequency in Hz
const char* rfport; // Port name
struct stream_cfg
{
long long bw_hz; // Analog banwidth in Hz
long long fs_hz; // Baseband sample rate in Hz
long long lo_hz; // Local oscillator frequency in Hz
const char *rfport; // Port name
};
/* check return value of attr_write function */
void errchk(int v, const char* what);
void errchk(int v, const char *what);
/* write attribute: long long int */
void wr_ch_lli(struct iio_channel *chn, const char* what, long long val);
void wr_ch_lli(struct iio_channel *chn, const char *what, long long val);
/* write attribute: string */
void wr_ch_str(struct iio_channel *chn, const char* what, const char* str);
void wr_ch_str(struct iio_channel *chn, const char *what, const char *str);
/* helper function generating channel names */
char* get_ch_name(const char* type, int id, char* tmpstr);
char *get_ch_name(const char *type, int id, char *tmpstr);
/* returns ad9361 phy device */
struct iio_device* get_ad9361_phy(struct iio_context *ctx);
struct iio_device *get_ad9361_phy(struct iio_context *ctx);
/* finds AD9361 streaming IIO devices */
bool get_ad9361_stream_dev(struct iio_context *ctx, enum iodev d, struct iio_device **dev);
@ -83,45 +88,43 @@ bool get_lo_chan(struct iio_context *ctx, enum iodev d, struct iio_channel **chn
/* applies streaming configuration through IIO */
bool cfg_ad9361_streaming_ch(struct iio_context *ctx, struct stream_cfg *cfg, enum iodev type, int chid);
bool config_ad9361_rx_local(unsigned long bandwidth_,
unsigned long sample_rate_,
unsigned long freq_,
std::string rf_port_select_,
std::string gain_mode_rx1_,
std::string gain_mode_rx2_,
double rf_gain_rx1_,
double rf_gain_rx2_);
unsigned long sample_rate_,
unsigned long freq_,
std::string rf_port_select_,
std::string gain_mode_rx1_,
std::string gain_mode_rx2_,
double rf_gain_rx1_,
double rf_gain_rx2_);
bool config_ad9361_rx_remote(std::string remote_host,
unsigned long bandwidth_,
unsigned long sample_rate_,
unsigned long freq_,
std::string rf_port_select_,
std::string gain_mode_rx1_,
std::string gain_mode_rx2_,
double rf_gain_rx1_,
double rf_gain_rx2_);
unsigned long bandwidth_,
unsigned long sample_rate_,
unsigned long freq_,
std::string rf_port_select_,
std::string gain_mode_rx1_,
std::string gain_mode_rx2_,
double rf_gain_rx1_,
double rf_gain_rx2_);
bool config_ad9361_lo_local(unsigned long bandwidth_,
unsigned long sample_rate_,
unsigned long freq_rf_tx_hz_,
double tx_attenuation_db_,
long long freq_dds_tx_hz_,
double scale_dds_dbfs_);
unsigned long sample_rate_,
unsigned long freq_rf_tx_hz_,
double tx_attenuation_db_,
long long freq_dds_tx_hz_,
double scale_dds_dbfs_);
bool config_ad9361_lo_remote(std::string remote_host,
unsigned long bandwidth_,
unsigned long sample_rate_,
unsigned long freq_rf_tx_hz_,
double tx_attenuation_db_,
long long freq_dds_tx_hz_,
double scale_dds_dbfs_);
unsigned long bandwidth_,
unsigned long sample_rate_,
unsigned long freq_rf_tx_hz_,
double tx_attenuation_db_,
long long freq_dds_tx_hz_,
double scale_dds_dbfs_);
bool ad9361_disable_lo_remote(std::string remote_host);
bool ad9361_disable_lo_local();
#endif

View File

@ -24,7 +24,8 @@ set(TELEMETRY_DECODER_ADAPTER_SOURCES
galileo_e1b_telemetry_decoder.cc
sbas_l1_telemetry_decoder.cc
galileo_e5a_telemetry_decoder.cc
glonass_l1_ca_telemetry_decoder.cc
glonass_l1_ca_telemetry_decoder.cc
glonass_l2_ca_telemetry_decoder.cc
)
include_directories(

View File

@ -0,0 +1,103 @@
/*!
* \file glonass_l2_ca_telemetry_decoder.cc
* \brief Implementation of an adapter of a GLONASS L2 C/A NAV data decoder block
* to a TelemetryDecoderInterface
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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 "glonass_l2_ca_telemetry_decoder.h"
#include "configuration_interface.h"
#include "glonass_gnav_ephemeris.h"
#include "glonass_gnav_almanac.h"
#include "glonass_gnav_utc_model.h"
#include <gnuradio/io_signature.h>
#include <glog/logging.h>
using google::LogMessage;
GlonassL2CaTelemetryDecoder::GlonassL2CaTelemetryDecoder(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams) : role_(role),
in_streams_(in_streams),
out_streams_(out_streams)
{
std::string default_dump_filename = "./navigation.dat";
DLOG(INFO) << "role " << role;
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
// make telemetry decoder object
telemetry_decoder_ = glonass_l2_ca_make_telemetry_decoder_cc(satellite_, dump_);
DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")";
channel_ = 0;
}
GlonassL2CaTelemetryDecoder::~GlonassL2CaTelemetryDecoder()
{
}
void GlonassL2CaTelemetryDecoder::set_satellite(const Gnss_Satellite& satellite)
{
satellite_ = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
telemetry_decoder_->set_satellite(satellite_);
DLOG(INFO) << "TELEMETRY DECODER: satellite set to " << satellite_;
}
void GlonassL2CaTelemetryDecoder::connect(gr::top_block_sptr top_block)
{
if (top_block)
{ /* top_block is not null */
};
// Nothing to connect internally
DLOG(INFO) << "nothing to connect internally";
}
void GlonassL2CaTelemetryDecoder::disconnect(gr::top_block_sptr top_block)
{
if (top_block)
{ /* top_block is not null */
};
// Nothing to disconnect
}
gr::basic_block_sptr GlonassL2CaTelemetryDecoder::get_left_block()
{
return telemetry_decoder_;
}
gr::basic_block_sptr GlonassL2CaTelemetryDecoder::get_right_block()
{
return telemetry_decoder_;
}

View File

@ -0,0 +1,90 @@
/*!
* \file glonass_l2_ca_telemetry_decoder.h
* \brief Interface of an adapter of a GLONASS L2 C/A NAV data decoder block
* to a TelemetryDecoderInterface
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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_GLONASS_L2_CA_TELEMETRY_DECODER_H_
#define GNSS_SDR_GLONASS_L2_CA_TELEMETRY_DECODER_H_
#include "telemetry_decoder_interface.h"
#include "glonass_l2_ca_telemetry_decoder_cc.h"
#include <string>
class ConfigurationInterface;
/*!
* \brief This class implements a NAV data decoder for GLONASS L2 C/A
*/
class GlonassL2CaTelemetryDecoder : public TelemetryDecoderInterface
{
public:
GlonassL2CaTelemetryDecoder(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams);
virtual ~GlonassL2CaTelemetryDecoder();
std::string role() override
{
return role_;
}
//! Returns "GLONASS_L2_CA_Telemetry_Decoder"
std::string implementation() override
{
return "GLONASS_L2_CA_Telemetry_Decoder";
}
void connect(gr::top_block_sptr top_block) override;
void disconnect(gr::top_block_sptr top_block) override;
gr::basic_block_sptr get_left_block() override;
gr::basic_block_sptr get_right_block() override;
void set_satellite(const Gnss_Satellite& satellite) override;
void set_channel(int channel) override { telemetry_decoder_->set_channel(channel); }
void reset() override
{
return;
}
size_t item_size() override
{
return 0;
}
private:
glonass_l2_ca_telemetry_decoder_cc_sptr telemetry_decoder_;
Gnss_Satellite satellite_;
int channel_;
bool dump_;
std::string dump_filename_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
};
#endif

View File

@ -24,6 +24,7 @@ set(TELEMETRY_DECODER_GR_BLOCKS_SOURCES
sbas_l1_telemetry_decoder_cc.cc
galileo_e5a_telemetry_decoder_cc.cc
glonass_l1_ca_telemetry_decoder_cc.cc
glonass_l2_ca_telemetry_decoder_cc.cc
)
include_directories(

View File

@ -320,7 +320,7 @@ int galileo_e1b_telemetry_decoder_cc::general_work(int noutput_items __attribute
d_stat = 1; // enter into frame pre-detection status
}
}
else if (d_stat == 1) // posible preamble lock
else if (d_stat == 1) // possible preamble lock
{
if (abs(corr_value) >= d_symbols_per_preamble)
{
@ -399,32 +399,32 @@ int galileo_e1b_telemetry_decoder_cc::general_work(int noutput_items __attribute
if (d_nav.flag_TOW_5 == true) //page 5 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec)
{
//TOW_5 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay
d_TOW_at_current_symbol = d_nav.TOW_5 + GALILEO_INAV_PAGE_PART_SECONDS + (static_cast<double>(required_symbols)) * GALILEO_E1_CODE_PERIOD; //-GALILEO_E1_CODE_PERIOD;//+ (double)GALILEO_INAV_PREAMBLE_LENGTH_BITS/(double)GALILEO_TELEMETRY_RATE_BITS_SECOND;
d_TOW_at_current_symbol = d_nav.TOW_5 + static_cast<double>(GALILEO_INAV_PAGE_PART_SECONDS) + static_cast<double>(required_symbols - 1) * GALILEO_E1_CODE_PERIOD; //-GALILEO_E1_CODE_PERIOD;//+ (double)GALILEO_INAV_PREAMBLE_LENGTH_BITS/(double)GALILEO_TELEMETRY_RATE_BITS_SECOND;
d_nav.flag_TOW_5 = false;
}
else if (d_nav.flag_TOW_6 == true) //page 6 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec)
{
//TOW_6 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay
d_TOW_at_current_symbol = d_nav.TOW_6 + GALILEO_INAV_PAGE_PART_SECONDS + (static_cast<double>(required_symbols)) * GALILEO_E1_CODE_PERIOD; //-GALILEO_E1_CODE_PERIOD;//+ (double)GALILEO_INAV_PREAMBLE_LENGTH_BITS/(double)GALILEO_TELEMETRY_RATE_BITS_SECOND;
d_TOW_at_current_symbol = d_nav.TOW_6 + static_cast<double>(GALILEO_INAV_PAGE_PART_SECONDS) + static_cast<double>(required_symbols - 1) * GALILEO_E1_CODE_PERIOD; //-GALILEO_E1_CODE_PERIOD;//+ (double)GALILEO_INAV_PREAMBLE_LENGTH_BITS/(double)GALILEO_TELEMETRY_RATE_BITS_SECOND;
d_nav.flag_TOW_6 = false;
}
else
{
//this page has no timing information
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALILEO_E1_CODE_PERIOD; // + GALILEO_INAV_PAGE_PART_SYMBOLS*GALILEO_E1_CODE_PERIOD;
d_TOW_at_current_symbol += GALILEO_E1_CODE_PERIOD; // + GALILEO_INAV_PAGE_PART_SYMBOLS*GALILEO_E1_CODE_PERIOD;
}
}
else //if there is not a new preamble, we define the TOW of the current symbol
{
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALILEO_E1_CODE_PERIOD;
d_TOW_at_current_symbol += GALILEO_E1_CODE_PERIOD;
}
//if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true and d_nav.flag_CRC_test == true)
if (d_nav.flag_GGTO_1 == true and d_nav.flag_GGTO_2 == true and d_nav.flag_GGTO_3 == true and d_nav.flag_GGTO_4 == true) //all GGTO parameters arrived
{
delta_t = d_nav.A_0G_10 + d_nav.A_1G_10 * (d_TOW_at_current_symbol - d_nav.t_0G_10 + 604800.0 * (fmod((d_nav.WN_0 - d_nav.WN_0G_10), 64)));
delta_t = d_nav.A_0G_10 + d_nav.A_1G_10 * (d_TOW_at_current_symbol - d_nav.t_0G_10 + 604800.0 * (fmod((d_nav.WN_0 - d_nav.WN_0G_10), 64.0)));
}
if (d_flag_frame_sync == true and d_nav.flag_TOW_set == true)

View File

@ -338,7 +338,7 @@ int galileo_e5a_telemetry_decoder_cc::general_work(int noutput_items __attribute
d_stat = 1; // enter into frame pre-detection status
}
}
else if ((d_stat == 1) && new_symbol) // posible preamble lock
else if ((d_stat == 1) && new_symbol) // possible preamble lock
{
if (abs(corr_value) >= GALILEO_FNAV_PREAMBLE_LENGTH_BITS)
{

View File

@ -271,7 +271,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the preamble sample stamp
}
}
else if (d_stat == 1) // posible preamble lock
else if (d_stat == 1) // possible preamble lock
{
if (abs(corr_value) >= d_symbols_per_preamble)
{

View File

@ -34,13 +34,13 @@
#define GNSS_SDR_GLONASS_L1_CA_TELEMETRY_DECODER_CC_H
#include "GLONASS_L1_CA.h"
#include "glonass_gnav_navigation_message.h"
#include "glonass_gnav_ephemeris.h"
#include "glonass_gnav_almanac.h"
#include "glonass_gnav_utc_model.h"
#include "gnss_satellite.h"
#include "gnss_synchro.h"
#include "GLONASS_L1_L2_CA.h"
#include <gnuradio/block.h>
#include <fstream>
#include <string>

View File

@ -0,0 +1,449 @@
/*!
* \file glonass_l2_ca_telemetry_decoder_cc.cc
* \brief Implementation of an adapter of a GLONASS L1 C/A NAV data decoder block
* to a TelemetryDecoderInterface
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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 "glonass_l2_ca_telemetry_decoder_cc.h"
#include <boost/lexical_cast.hpp>
#include <gnuradio/io_signature.h>
#include <glog/logging.h>
#define CRC_ERROR_LIMIT 6
using google::LogMessage;
glonass_l2_ca_telemetry_decoder_cc_sptr
glonass_l2_ca_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump)
{
return glonass_l2_ca_telemetry_decoder_cc_sptr(new glonass_l2_ca_telemetry_decoder_cc(satellite, dump));
}
glonass_l2_ca_telemetry_decoder_cc::glonass_l2_ca_telemetry_decoder_cc(
const Gnss_Satellite &satellite,
bool dump) : gr::block("glonass_l2_ca_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{
// Telemetry Bit transition synchronization port out
this->message_port_register_out(pmt::mp("preamble_timestamp_s"));
// Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry"));
// initialize internal vars
d_dump = dump;
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
LOG(INFO) << "Initializing GLONASS L2 CA TELEMETRY DECODING";
// Define the number of sampes per symbol. Notice that GLONASS has 2 rates,
//one for the navigation data and the other for the preamble information
d_samples_per_symbol = (GLONASS_L2_CA_CODE_RATE_HZ / GLONASS_L2_CA_CODE_LENGTH_CHIPS) / GLONASS_L2_CA_SYMBOL_RATE_BPS;
// Set the preamble information
unsigned short int preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS] = GLONASS_GNAV_PREAMBLE;
// Since preamble rate is different than navigation data rate we use a constant
d_symbols_per_preamble = GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS;
memcpy(static_cast<unsigned short int *>(this->d_preambles_bits), static_cast<unsigned short int *>(preambles_bits), GLONASS_GNAV_PREAMBLE_LENGTH_BITS * sizeof(unsigned short int));
// preamble bits to sampled symbols
d_preambles_symbols = static_cast<signed int *>(malloc(sizeof(signed int) * d_symbols_per_preamble));
int n = 0;
for (int i = 0; i < GLONASS_GNAV_PREAMBLE_LENGTH_BITS; i++)
{
for (unsigned int j = 0; j < GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_PREAMBLE_BIT; j++)
{
if (d_preambles_bits[i] == 1)
{
d_preambles_symbols[n] = 1;
}
else
{
d_preambles_symbols[n] = -1;
}
n++;
}
}
d_sample_counter = 0;
d_stat = 0;
d_preamble_index = 0;
d_flag_frame_sync = false;
d_flag_parity = false;
d_TOW_at_current_symbol = 0;
Flag_valid_word = false;
delta_t = 0;
d_CRC_error_counter = 0;
d_flag_preamble = false;
d_channel = 0;
flag_TOW_set = false;
d_preamble_time_samples = 0;
}
glonass_l2_ca_telemetry_decoder_cc::~glonass_l2_ca_telemetry_decoder_cc()
{
delete d_preambles_symbols;
if (d_dump_file.is_open() == true)
{
try
{
d_dump_file.close();
}
catch (const std::exception &ex)
{
LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what();
}
}
}
void glonass_l2_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, int frame_length)
{
double chip_acc = 0.0;
int chip_acc_counter = 0;
// 1. Transform from symbols to bits
std::string bi_binary_code;
std::string relative_code;
std::string data_bits;
// Group samples into bi-binary code
for (int i = 0; i < (frame_length); i++)
{
chip_acc += frame_symbols[i];
chip_acc_counter += 1;
if (chip_acc_counter == (GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_BIT))
{
if (chip_acc > 0)
{
bi_binary_code.push_back('1');
chip_acc_counter = 0;
chip_acc = 0;
}
else
{
bi_binary_code.push_back('0');
chip_acc_counter = 0;
chip_acc = 0;
}
}
}
// Convert from bi-binary code to relative code
for (int i = 0; i < (GLONASS_GNAV_STRING_BITS); i++)
{
if (bi_binary_code[2 * i] == '1' && bi_binary_code[2 * i + 1] == '0')
{
relative_code.push_back('1');
}
else
{
relative_code.push_back('0');
}
}
// Convert from relative code to data bits
data_bits.push_back('0');
for (int i = 1; i < (GLONASS_GNAV_STRING_BITS); i++)
{
data_bits.push_back(((relative_code[i - 1] - '0') ^ (relative_code[i] - '0')) + '0');
}
// 2. Call the GLONASS GNAV string decoder
d_nav.string_decoder(data_bits);
// 3. Check operation executed correctly
if (d_nav.flag_CRC_test == true)
{
LOG(INFO) << "GLONASS GNAV CRC correct on channel " << d_channel << " from satellite " << d_satellite;
}
else
{
LOG(INFO) << "GLONASS GNAV CRC error on channel " << d_channel << " from satellite " << d_satellite;
}
// 4. Push the new navigation data to the queues
if (d_nav.have_new_ephemeris() == true)
{
// get object for this SV (mandatory)
d_nav.gnav_ephemeris.i_satellite_freq_channel = d_satellite.get_rf_link();
std::shared_ptr<Glonass_Gnav_Ephemeris> tmp_obj = std::make_shared<Glonass_Gnav_Ephemeris>(d_nav.get_ephemeris());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "GLONASS GNAV Ephemeris have been received on channel" << d_channel << " from satellite " << d_satellite;
}
if (d_nav.have_new_utc_model() == true)
{
// get object for this SV (mandatory)
std::shared_ptr<Glonass_Gnav_Utc_Model> tmp_obj = std::make_shared<Glonass_Gnav_Utc_Model>(d_nav.get_utc_model());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "GLONASS GNAV UTC Model have been received on channel" << d_channel << " from satellite " << d_satellite;
}
if (d_nav.have_new_almanac() == true)
{
unsigned int slot_nbr = d_nav.i_alm_satellite_slot_number;
std::shared_ptr<Glonass_Gnav_Almanac> tmp_obj = std::make_shared<Glonass_Gnav_Almanac>(d_nav.get_almanac(slot_nbr));
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "GLONASS GNAV Almanac have been received on channel" << d_channel << " in slot number " << slot_nbr;
}
// 5. Update satellite information on system
if (d_nav.flag_update_slot_number == true)
{
LOG(INFO) << "GLONASS GNAV Slot Number Identified on channel " << d_channel;
d_satellite.update_PRN(d_nav.gnav_ephemeris.d_n);
d_satellite.what_block(d_satellite.get_system(), d_nav.gnav_ephemeris.d_n);
d_nav.flag_update_slot_number = false;
}
}
int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{
int corr_value = 0;
int preamble_diff = 0;
Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); // Get the output buffer pointer
const Gnss_Synchro **in = reinterpret_cast<const Gnss_Synchro **>(&input_items[0]); // Get the input buffer pointer
Gnss_Synchro current_symbol; //structure to save the synchronization information and send the output object to the next block
//1. Copy the current tracking output
current_symbol = in[0][0];
d_symbol_history.push_back(current_symbol); //add new symbol to the symbol queue
d_sample_counter++; //count for the processed samples
consume_each(1);
d_flag_preamble = false;
unsigned int required_symbols = GLONASS_GNAV_STRING_SYMBOLS;
if (d_symbol_history.size() > required_symbols)
{
//******* preamble correlation ********
for (int i = 0; i < d_symbols_per_preamble; i++)
{
if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping
{
corr_value -= d_preambles_symbols[i];
}
else
{
corr_value += d_preambles_symbols[i];
}
}
}
//******* frame sync ******************
if (d_stat == 0) //no preamble information
{
if (abs(corr_value) >= d_symbols_per_preamble)
{
// Record the preamble sample stamp
d_preamble_index = d_sample_counter;
LOG(INFO) << "Preamble detection for GLONASS L2 C/A SAT " << this->d_satellite;
// Enter into frame pre-detection status
d_stat = 1;
d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the preamble sample stamp
}
}
else if (d_stat == 1) // possible preamble lock
{
if (abs(corr_value) >= d_symbols_per_preamble)
{
//check preamble separation
preamble_diff = d_sample_counter - d_preamble_index;
// Record the PRN start sample index associated to the preamble
d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter;
if (abs(preamble_diff - GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) == 0)
{
//try to decode frame
LOG(INFO) << "Starting string decoder for GLONASS L2 C/A SAT " << this->d_satellite;
d_preamble_index = d_sample_counter; //record the preamble sample stamp
d_stat = 2;
// send asynchronous message to tracking to inform of frame sync and extend correlation time
pmt::pmt_t value = pmt::from_double(static_cast<double>(d_preamble_time_samples) / static_cast<double>(d_symbol_history.at(0).fs) - 0.001);
this->message_port_pub(pmt::mp("preamble_timestamp_s"), value);
}
else
{
if (preamble_diff > GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS)
{
d_stat = 0; // start again
}
DLOG(INFO) << "Failed string decoder for GLONASS L2 C/A SAT " << this->d_satellite;
}
}
}
else if (d_stat == 2)
{
// FIXME: The preamble index marks the first symbol of the string count. Here I just wait for another full string to be received before processing
if (d_sample_counter == d_preamble_index + GLONASS_GNAV_STRING_SYMBOLS)
{
// NEW GLONASS string received
// 0. fetch the symbols into an array
int string_length = GLONASS_GNAV_STRING_SYMBOLS - d_symbols_per_preamble;
double string_symbols[GLONASS_GNAV_DATA_SYMBOLS] = {0};
//******* SYMBOL TO BIT *******
for (int i = 0; i < string_length; i++)
{
if (corr_value > 0)
{
string_symbols[i] = d_symbol_history.at(i + d_symbols_per_preamble).Prompt_I; // because last symbol of the preamble is just received now!
}
else
{
string_symbols[i] = -d_symbol_history.at(i + d_symbols_per_preamble).Prompt_I; // because last symbol of the preamble is just received now!
}
}
//call the decoder
decode_string(string_symbols, string_length);
if (d_nav.flag_CRC_test == true)
{
d_CRC_error_counter = 0;
d_flag_preamble = true; //valid preamble indicator (initialized to false every work())
d_preamble_index = d_sample_counter; //record the preamble sample stamp (t_P)
if (!d_flag_frame_sync)
{
d_flag_frame_sync = true;
DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at "
<< d_symbol_history.at(0).Tracking_sample_counter << " [samples]";
}
}
else
{
d_CRC_error_counter++;
d_preamble_index = d_sample_counter; //record the preamble sample stamp
if (d_CRC_error_counter > CRC_ERROR_LIMIT)
{
LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite;
d_flag_frame_sync = false;
d_stat = 0;
}
}
}
}
// UPDATE GNSS SYNCHRO DATA
//2. Add the telemetry decoder information
if (this->d_flag_preamble == true and d_nav.flag_TOW_new == true)
//update TOW at the preamble instant
{
d_TOW_at_current_symbol = floor((d_nav.gnav_ephemeris.d_TOW - GLONASS_GNAV_PREAMBLE_DURATION_S) * 1000) / 1000;
d_nav.flag_TOW_new = false;
}
else //if there is not a new preamble, we define the TOW of the current symbol
{
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GLONASS_L2_CA_CODE_PERIOD;
}
//if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true and d_nav.flag_CRC_test == true)
// if(d_nav.flag_GGTO_1 == true and d_nav.flag_GGTO_2 == true and d_nav.flag_GGTO_3 == true and d_nav.flag_GGTO_4 == true) //all GGTO parameters arrived
// {
// delta_t = d_nav.A_0G_10 + d_nav.A_1G_10 * (d_TOW_at_current_symbol - d_nav.t_0G_10 + 604800.0 * (fmod((d_nav.WN_0 - d_nav.WN_0G_10), 64)));
// }
if (d_flag_frame_sync == true and d_nav.flag_TOW_set == true)
{
current_symbol.Flag_valid_word = true;
}
else
{
current_symbol.Flag_valid_word = false;
}
current_symbol.PRN = this->d_satellite.get_PRN();
current_symbol.TOW_at_current_symbol_s = d_TOW_at_current_symbol;
current_symbol.TOW_at_current_symbol_s -= delta_t; // Galileo to GPS TOW
if (d_dump == true)
{
// MULTIPLEXED FILE RECORDING - Record results to file
try
{
double tmp_double;
unsigned long int tmp_ulong_int;
tmp_double = d_TOW_at_current_symbol;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_ulong_int = current_symbol.Tracking_sample_counter;
d_dump_file.write(reinterpret_cast<char *>(&tmp_ulong_int), sizeof(unsigned long int));
tmp_double = 0;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
}
catch (const std::ifstream::failure &e)
{
LOG(WARNING) << "Exception writing observables dump file " << e.what();
}
}
// remove used symbols from history
if (d_symbol_history.size() > required_symbols)
{
d_symbol_history.pop_front();
}
//3. Make the output (copy the object contents to the GNURadio reserved memory)
*out[0] = current_symbol;
return 1;
}
void glonass_l2_ca_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite)
{
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite;
DLOG(INFO) << "Navigation Satellite set to " << d_satellite;
}
void glonass_l2_ca_telemetry_decoder_cc::set_channel(int channel)
{
d_channel = channel;
LOG(INFO) << "Navigation channel set to " << channel;
// ############# ENABLE DATA FILE LOG #################
if (d_dump == true)
{
if (d_dump_file.is_open() == false)
{
try
{
d_dump_filename = "telemetry";
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);
LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str();
}
catch (const std::ifstream::failure &e)
{
LOG(WARNING) << "channel " << d_channel << ": exception opening Glonass TLM dump file. " << e.what();
}
}
}
}

View File

@ -0,0 +1,117 @@
/*!
* \file glonass_l2_ca_telemetry_decoder_cc.h
* \brief Implementation of an adapter of a GLONASS L2 C/A NAV data decoder block
* to a TelemetryDecoderInterface
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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_GLONASS_L2_CA_TELEMETRY_DECODER_CC_H
#define GNSS_SDR_GLONASS_L2_CA_TELEMETRY_DECODER_CC_H
#include "GLONASS_L1_L2_CA.h"
#include "glonass_gnav_navigation_message.h"
#include "glonass_gnav_ephemeris.h"
#include "glonass_gnav_almanac.h"
#include "glonass_gnav_utc_model.h"
#include "gnss_satellite.h"
#include "gnss_synchro.h"
#include <gnuradio/block.h>
#include <fstream>
#include <string>
class glonass_l2_ca_telemetry_decoder_cc;
typedef boost::shared_ptr<glonass_l2_ca_telemetry_decoder_cc> glonass_l2_ca_telemetry_decoder_cc_sptr;
glonass_l2_ca_telemetry_decoder_cc_sptr glonass_l2_ca_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump);
/*!
* \brief This class implements a block that decodes the GNAV data defined in GLONASS ICD v5.1
* \see <a href="http://russianspacesystems.ru/wp-content/uploads/2016/08/ICD_GLONASS_eng_v5.1.pdf">GLONASS ICD</a>
*
*/
class glonass_l2_ca_telemetry_decoder_cc : public gr::block
{
public:
~glonass_l2_ca_telemetry_decoder_cc(); //!< Class destructor
void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN
void set_channel(int channel); //!< Set receiver's channel
/*!
* \brief This is where all signal processing takes place
*/
int general_work(int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
private:
friend glonass_l2_ca_telemetry_decoder_cc_sptr
glonass_l2_ca_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump);
glonass_l2_ca_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump);
void decode_string(double *symbols, int frame_length);
//!< Help with coherent tracking
double d_preamble_time_samples;
//!< Preamble decoding
unsigned short int d_preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS];
int *d_preambles_symbols;
unsigned int d_samples_per_symbol;
int d_symbols_per_preamble;
//!< Storage for incoming data
std::deque<Gnss_Synchro> d_symbol_history;
//!< Variables for internal functionality
long unsigned int d_sample_counter; //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed
long unsigned int d_preamble_index; //!< Index of sample number where preamble was found
unsigned int d_stat; //!< Status of decoder
bool d_flag_frame_sync; //!< Indicate when a frame sync is achieved
bool d_flag_parity; //!< Flag indicating when parity check was achieved (crc check)
bool d_flag_preamble; //!< Flag indicating when preamble was found
int d_CRC_error_counter; //!< Number of failed CRC operations
bool flag_TOW_set; //!< Indicates when time of week is set
double delta_t; //!< GPS-GLONASS time offset
//!< Navigation Message variable
Glonass_Gnav_Navigation_Message d_nav;
//!< Values to populate gnss synchronization structure
double d_TOW_at_current_symbol;
bool Flag_valid_word;
//!< Satellite Information and logging capacity
Gnss_Satellite d_satellite;
int d_channel;
bool d_dump;
std::string d_dump_filename;
std::ofstream d_dump_file;
};
#endif

View File

@ -93,8 +93,8 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(
d_GPS_frame_4bytes = 0;
d_prev_GPS_frame_4bytes = 0;
d_flag_parity = false;
d_TOW_at_Preamble = 0;
d_TOW_at_current_symbol = 0;
d_TOW_at_Preamble = 0.0;
d_TOW_at_current_symbol = 0.0;
flag_TOW_set = false;
d_average_count = 0;
d_flag_preamble = false;
@ -104,6 +104,7 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(
d_channel = 0;
flag_PLL_180_deg_phase_locked = false;
d_preamble_time_samples = 0;
d_TOW_at_current_symbol_ms = 0;
}
@ -350,18 +351,22 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__
//double decoder_latency_ms=(double)(current_symbol.Tracking_sample_counter-d_symbol_history.at(0).Tracking_sample_counter)
// /(double)current_symbol.fs;
// update TOW at the preamble instant (account with decoder latency)
d_TOW_at_Preamble = d_GPS_FSM.d_nav.d_TOW + 2 * GPS_L1_CA_CODE_PERIOD + GPS_CA_PREAMBLE_DURATION_S;
d_TOW_at_current_symbol = floor(d_TOW_at_Preamble * 1000.0) / 1000.0;
d_TOW_at_Preamble = d_GPS_FSM.d_nav.d_TOW + 2.0 * GPS_L1_CA_CODE_PERIOD + GPS_CA_PREAMBLE_DURATION_S;
d_TOW_at_current_symbol_ms = static_cast<unsigned int>(d_GPS_FSM.d_nav.d_TOW) * 1000 + 161;
//d_TOW_at_current_symbol = floor(d_TOW_at_Preamble * 1000.0) / 1000.0;
d_TOW_at_current_symbol = d_TOW_at_Preamble;
flag_TOW_set = true;
d_flag_new_tow_available = false;
}
else
{
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GPS_L1_CA_CODE_PERIOD;
d_TOW_at_current_symbol += GPS_L1_CA_CODE_PERIOD;
d_TOW_at_current_symbol_ms += GPS_L1_CA_CODE_PERIOD_MS;
}
current_symbol.TOW_at_current_symbol_s = d_TOW_at_current_symbol;
current_symbol.TOW_at_current_symbol_s = static_cast<double>(d_TOW_at_current_symbol_ms) / 1000.0;
//current_symbol.TOW_at_current_symbol_s = d_TOW_at_current_symbol;
current_symbol.Flag_valid_word = flag_TOW_set;
if (flag_PLL_180_deg_phase_locked == true)

Some files were not shown because too many files have changed in this diff Show More