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:
commit
8e59a42ae2
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
||||
################################################################################
|
||||
|
@ -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
|
||||
|
44
README.md
44
README.md
@ -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).
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
141
conf/gnss-sdr_GLONASS_L2_CA_GPS_L1_CA_ibyte.conf
Normal file
141
conf/gnss-sdr_GLONASS_L2_CA_GPS_L1_CA_ibyte.conf
Normal 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
|
142
conf/gnss-sdr_GLONASS_L2_CA_GPS_L2C_ibyte.conf
Normal file
142
conf/gnss-sdr_GLONASS_L2_CA_GPS_L2C_ibyte.conf
Normal 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
|
73
conf/gnss-sdr_GLONASS_L2_CA_ibyte.conf
Normal file
73
conf/gnss-sdr_GLONASS_L2_CA_ibyte.conf
Normal 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
|
83
conf/gnss-sdr_GLONASS_L2_CA_ibyte_coh_trk.conf
Normal file
83
conf/gnss-sdr_GLONASS_L2_CA_ibyte_coh_trk.conf
Normal 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
|
112
conf/gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf
Normal file
112
conf/gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf
Normal 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
|
@ -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
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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_);
|
||||
|
@ -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;
|
||||
|
@ -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_);
|
||||
|
@ -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_;
|
||||
}
|
@ -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_ */
|
@ -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_);
|
||||
|
@ -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_);
|
||||
|
@ -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_);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
152
src/algorithms/libs/glonass_l2_signal_processing.cc
Normal file
152
src/algorithms/libs/glonass_l2_signal_processing.cc
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
47
src/algorithms/libs/glonass_l2_signal_processing.h
Normal file
47
src/algorithms/libs/glonass_l2_signal_processing.h
Normal 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_ */
|
@ -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;
|
||||
}
|
||||
|
@ -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_*/
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
@ -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_;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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) */
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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_;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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};
|
||||
|
@ -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
|
||||
*-----------------------------------------------------------------------------*/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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})
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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*/
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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_;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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_;
|
||||
}
|
@ -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
|
@ -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(
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
@ -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
Loading…
Reference in New Issue
Block a user