mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-12 19:20:32 +00:00
Merge with next and enabling KF VTL experimental tracking
This commit is contained in:
commit
56943fc12d
41
.github/DCO.txt
vendored
Normal file
41
.github/DCO.txt
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
Copyright (C) 2021 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)
|
||||
and its contributors.
|
||||
|
||||
Parc Mediterrani de la Tecnologia (PMT)
|
||||
Building B4
|
||||
Av. Carl Friedrich Gauss 7
|
||||
08860 - Castelldefels (Spain)
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
34
.github/PULL_REQUEST_TEMPLATE.md
vendored
34
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -7,25 +7,35 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
)
|
||||
|
||||
[comment]: # (
|
||||
SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es>
|
||||
SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es>
|
||||
)
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
Any code contributions going into GNSS-SDR will become part of a GPL-licensed,
|
||||
open source repository. It is therefore imperative that code submissions belong
|
||||
to the authors, and that submitters have the authority to merge that code into
|
||||
the public GNSS-SDR codebase.
|
||||
|
||||
For that purpose, we use the
|
||||
[Developer's Certificate of Origin](https://github.com/gnss-sdr/gnss-sdr/blob/next/.github/DCO.txt).
|
||||
It is the same document used by other projects. Signing the DCO states that
|
||||
there are no legal reasons to not merge your code.
|
||||
|
||||
To sign the DCO, suffix your git commits with a `Signed-off-by:` line. When
|
||||
using the command line, you can use `git commit -s` to automatically add this
|
||||
line. If there were multiple authors of the code, or other types of
|
||||
stakeholders, make sure that all are listed, each with a separate
|
||||
`Signed-off-by:` line.
|
||||
|
||||
Before submitting your pull request, please make sure the following is done:
|
||||
|
||||
1. You undertake the
|
||||
[Contributor Covenant Code of Conduct](https://github.com/gnss-sdr/gnss-sdr/blob/master/CODE_OF_CONDUCT.md).
|
||||
2. If you are a first-time contributor, after your pull request you will be
|
||||
asked to sign an Individual Contributor License Agreement
|
||||
([CLA](https://en.wikipedia.org/wiki/Contributor_License_Agreement)) before
|
||||
your code gets accepted into `master`. This license is for your protection
|
||||
as a Contributor as well as for the protection of
|
||||
[CTTC](http://www.cttc.es/); it does not change your rights to use your own
|
||||
contributions for any other purpose. Except for the license granted therein
|
||||
to CTTC and recipients of software distributed by CTTC, you reserve all
|
||||
right, title, and interest in and to your contributions. The information you
|
||||
provide in that CLA will be maintained in accordance with
|
||||
[CTTC's privacy policy](http://www.cttc.es/privacy/).
|
||||
2. You have read the
|
||||
[Developer's Certificate of Origin](https://github.com/gnss-sdr/gnss-sdr/blob/next/.github/DCO.txt)
|
||||
and
|
||||
[signed your commits](https://gnss-sdr.org/docs/tutorials/using-git/#sign-your-commits)
|
||||
as an indication of fulfillment.
|
||||
3. You have read the
|
||||
[Contributing Guidelines](https://github.com/gnss-sdr/gnss-sdr/blob/master/CONTRIBUTING.md).
|
||||
4. You have read the [coding style guide](https://gnss-sdr.org/coding-style/).
|
||||
|
1
AUTHORS
1
AUTHORS
@ -51,6 +51,7 @@ David Pubill david.pubill@cttc.cat Contributor
|
||||
Fran Fabra fabra@ice.csic.es Contributor
|
||||
Gabriel Araujo gabriel.araujo.5000@gmail.com Contributor
|
||||
Gerald LaMountain gerald@gece.neu.edu Contributor
|
||||
Jim Melton jim.melton@sncorp.com Contributor
|
||||
Josh Schindehette jschindehette@geontech.com Contributor
|
||||
Leonardo Tonetto tonetto.dev@gmail.com Contributor
|
||||
Mara Branzanti mara.branzanti@gmail.com Contributor
|
||||
|
@ -332,7 +332,7 @@ set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master")
|
||||
set(GNSSSDR_GPSTK_LOCAL_VERSION "8.0.0")
|
||||
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.19")
|
||||
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.11.4")
|
||||
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.14.0")
|
||||
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.15.0")
|
||||
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.5.2")
|
||||
set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7")
|
||||
|
||||
|
@ -6,7 +6,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
)
|
||||
|
||||
[comment]: # (
|
||||
SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es>
|
||||
SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es>
|
||||
)
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
@ -116,8 +116,11 @@ $ git checkout -b my_feature
|
||||
```
|
||||
|
||||
Now you can do changes, add files, do commits (please take a look at
|
||||
[how to write good commit messages](https://chris.beams.io/posts/git-commit/)!)
|
||||
and push them to your repository:
|
||||
[how to write good commit messages](https://chris.beams.io/posts/git-commit/),
|
||||
and do not forget to
|
||||
[sign your commits](https://gnss-sdr.org/docs/tutorials/using-git/#sign-your-commits)
|
||||
if you plan to submit your code to the upstream repository in a pull-request,
|
||||
see below) and push them to your repository:
|
||||
|
||||
```
|
||||
$ git push origin my_feature
|
||||
@ -133,6 +136,24 @@ $ git pull --rebase upstream next
|
||||
|
||||
### How to submit a pull request
|
||||
|
||||
Any code contributions going into GNSS-SDR will become part of a GPL-licensed,
|
||||
open source repository. It is therefore imperative that code submissions belong
|
||||
to the authors, and that submitters have the authority to merge that code into
|
||||
the public GNSS-SDR codebase.
|
||||
|
||||
For that purpose, we use the
|
||||
[Developer's Certificate of Origin](https://github.com/gnss-sdr/gnss-sdr/blob/next/.github/DCO.txt).
|
||||
It is the same document used by other projects. Signing the DCO states that
|
||||
there are no legal reasons to not merge your code.
|
||||
|
||||
To sign the DCO, suffix your git commits with a `Signed-off-by:` line. When
|
||||
using the command line, you can use `git commit -s` to automatically add this
|
||||
line. If there were multiple authors of the code, or other types of
|
||||
stakeholders, make sure that all are listed, each with a separate
|
||||
`Signed-off-by:` line. See
|
||||
[how to sign commits](https://gnss-sdr.org/docs/tutorials/using-git/#sign-your-commits)
|
||||
for details on how to tell Git to sign commits by default.
|
||||
|
||||
Before submitting your code, please be sure to
|
||||
[apply clang-format](https://gnss-sdr.org/coding-style/#use-tools-for-automated-code-formatting).
|
||||
|
||||
@ -147,6 +168,7 @@ discuss potential modifications, and even push follow-up commits if necessary.
|
||||
|
||||
Some things that will increase the chance that your pull request is accepted:
|
||||
|
||||
- Your commits must be signed.
|
||||
- Avoid platform-dependent code. If your code require external dependencies,
|
||||
they must be available as packages in
|
||||
[Debian OldStable](https://wiki.debian.org/DebianOldStable).
|
||||
|
@ -122,7 +122,10 @@ endif()
|
||||
# All of our tests require C++17 or later
|
||||
set(OLD_CMAKE_CXX_STANDARD ${CMAKE_CXX_STANDARD})
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "9.0.0"))
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "8.0.0"))
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.99")
|
||||
set(UNDEFINED_BEHAVIOR_WITHOUT_LINKING TRUE)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_FLAGS "-std=c++17")
|
||||
endif()
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.99"))
|
||||
@ -207,9 +210,10 @@ if(CXX_FILESYSTEM_HAVE_FS)
|
||||
]] code @ONLY)
|
||||
|
||||
# Try to compile a simple filesystem program without any linker flags
|
||||
check_cxx_source_compiles("${code}" CXX_FILESYSTEM_NO_LINK_NEEDED)
|
||||
|
||||
set(can_link ${CXX_FILESYSTEM_NO_LINK_NEEDED})
|
||||
if(NOT UNDEFINED_BEHAVIOR_WITHOUT_LINKING)
|
||||
check_cxx_source_compiles("${code}" CXX_FILESYSTEM_NO_LINK_NEEDED)
|
||||
set(can_link ${CXX_FILESYSTEM_NO_LINK_NEEDED})
|
||||
endif()
|
||||
|
||||
if(NOT CXX_FILESYSTEM_NO_LINK_NEEDED)
|
||||
set(prev_libraries ${CMAKE_REQUIRED_LIBRARIES})
|
||||
|
@ -22,14 +22,29 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
|
||||
- Fix building when using the Xcode generator, Xcode >= 12 and CMake >= 3.19.
|
||||
- Fix building of FPGA blocks when linking against GNU Radio >= 3.9 and/or
|
||||
Boost >= 1.74.
|
||||
- Fix linking of the `<filesystem>` library when using GCC 8.x and GNU Radio >=
|
||||
3.8.
|
||||
|
||||
### Improvements in Maintainability:
|
||||
|
||||
- The Contributor License Agreement (CLA) signing for new contributors has been
|
||||
replaced by a
|
||||
[Developer's Certificate of Origin (DCO)](https://github.com/gnss-sdr/gnss-sdr/blob/next/.github/DCO.txt),
|
||||
which implies that contributed commits in a pull request need to be signed as
|
||||
a manifestation that contributors have the right to submit their work under
|
||||
the open source license indicated in the contributed file(s) (instead of
|
||||
asking them to sign the CLA document).
|
||||
- Improved handling of change in GNU Radio 3.9 FFT API.
|
||||
- Improved handling of the filesystem library.
|
||||
- Added an abstract class `SignalSourceInterface` and a common base class
|
||||
`SignalSourceBase`, which allow to remove a lot of duplicated code in Signal
|
||||
Source blocks, and further abstract file-based interfaces behind them.
|
||||
- Do not apply clang-tidy fixes to protobuf-generated headers.
|
||||
- Refactored private implementation of flow graph connection and disconnection
|
||||
for improved source code readability.
|
||||
- Added a base class for GNSS ephemeris, saving some duplicated code and
|
||||
providing a common nomenclature for ephemeris' parameters. New generated XML
|
||||
files make use of the new parameters' name.
|
||||
|
||||
### Improvements in Usability:
|
||||
|
||||
@ -37,6 +52,9 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
|
||||
some common inconsistencies in the configuration file.
|
||||
- Provide hints to the user in case of failed flow graph connection due to
|
||||
inconsistencies in the configuration file.
|
||||
- Fix segmentation fault if the RINEX output was disabled.
|
||||
- Added a feature that optionally enables the remote monitoring of GPS and
|
||||
Galileo ephemeris using UDP and protobuffers.
|
||||
|
||||
|
||||
|
||||
|
@ -105,9 +105,10 @@ Google submitted KML (formerly Keyhole Markup Language) to the Open Geospatial C
|
||||
|
||||
The C++ programming language is standardized by the International Organization for Standardization (ISO), with the latest standard version ratified and published by ISO in December 2017 as ISO/IEC 14882:2017 (informally known as C++17). The list of supported C++ standards (the highest available is automatically selected by the CMake script):
|
||||
<ul>
|
||||
<li><strong>Draft C++20</strong>: Check the <a href="https://github.com/cplusplus/draft" target="_blank">C++ standard draft sources at GitHub</a>.</li>
|
||||
<li><strong>C++17</strong>: The current ISO C++ standard is officially known as <em>ISO International Standard ISO/IEC 14882:2017 – Programming languages – C++</em>. You can get it from <a href="https://www.iso.org/standard/68564.html" target="_blank">ISO</a>, <a href="https://webstore.iec.ch/publication/62162" target="_blank">IEC</a> or <a href="https://webstore.ansi.org/Standards/ISO/ISOIEC148822017" target="_blank">ANSI</a>. The closest free working document available is <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf" target="_blank">N4659</a>.</li>
|
||||
<li><strong>C++14</strong>: The former ISO C++ standard was officially known as <em>ISO International Standard ISO/IEC 14882:2014 – Programming languages – C++</em>. You can get it from <a href="https://www.iso.org/standard/64029.html" target="_blank">ISO</a> or <a href="https://webstore.ansi.org/RecordDetail.aspx?sku=INCITS/ISO/IEC+14882:2014+(2016)" target="_blank">ANSI</a>. The closest free working document available is <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf" target="_blank">N4296</a>.</li>
|
||||
<li><strong>Draft C++23</strong>: Check the <a href="https://github.com/cplusplus/draft" target="_blank">C++ standard draft sources at GitHub</a>.</li>
|
||||
<li><strong>C++20</strong>: The current ISO C++ standard is officially known as <em>ISO International Standard ISO/IEC 14882:2020(E) – Programming languages – C++</em>. You can get it from <a href="https://www.iso.org/standard/79358.html" target="_blank">ISO</a>, <a href="https://webstore.iec.ch/publication/68285" target="_blank">IEC</a> or <a href="https://webstore.ansi.org/Standards/ISO/ISOIEC148822020" target="_blank">ANSI</a>. The closest free working document available is <a href="https://github.com/cplusplus/draft/releases/download/n4868/n4868.pdf" target="_blank">N4868</a>.</li>
|
||||
<li><strong>C++17</strong>: A former ISO C++ standard was officially known as <em>ISO International Standard ISO/IEC 14882:2017 – Programming languages – C++</em>. You can get it from <a href="https://www.iso.org/standard/68564.html" target="_blank">ISO</a>, <a href="https://webstore.iec.ch/publication/62162" target="_blank">IEC</a> or <a href="https://webstore.ansi.org/Standards/ISO/ISOIEC148822017" target="_blank">ANSI</a>. The closest free working document available is <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf" target="_blank">N4659</a>.</li>
|
||||
<li><strong>C++14</strong>: A former ISO C++ standard was officially known as <em>ISO International Standard ISO/IEC 14882:2014 – Programming languages – C++</em>. You can get it from <a href="https://www.iso.org/standard/64029.html" target="_blank">ISO</a> or <a href="https://webstore.ansi.org/RecordDetail.aspx?sku=INCITS/ISO/IEC+14882:2014+(2016)" target="_blank">ANSI</a>. The closest free working document available is <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf" target="_blank">N4296</a>.</li>
|
||||
<li><strong>C++11</strong>: An older ISO C++ standard was ISO/IEC 14882:2011. You can get it from <a href="https://www.iso.org/standard/50372.html" target="_blank">ISO</a>. The closest free working document available is <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf" target="_blank">N3337</a>.</li>
|
||||
</ul>
|
||||
|
||||
|
53
docs/protobuf/galileo_ephemeris.proto
Normal file
53
docs/protobuf/galileo_ephemeris.proto
Normal file
@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2018-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es>
|
||||
syntax = "proto3";
|
||||
|
||||
package gnss_sdr;
|
||||
|
||||
message GalileoEphemeris {
|
||||
int32 PRN = 1; // SV ID
|
||||
double M_0 = 2; // Mean anomaly at reference time [semi-circles]
|
||||
double delta_n = 3; // Mean motion difference from computed value [semi-circles/sec]
|
||||
double ecc = 4; // Eccentricity
|
||||
double sqrtA = 5; // Square root of the semi-major axis [meters^1/2]
|
||||
double OMEGA_0 = 6; // Longitude of ascending node of orbital plane at weekly epoch [semi-circles]
|
||||
double i_0 = 7; // Inclination angle at reference time [semi-circles]
|
||||
double omega = 8; // Argument of perigee [semi-circles]
|
||||
double OMEGAdot = 9; // Rate of right ascension [semi-circles/sec]
|
||||
double idot = 10; // Rate of inclination angle [semi-circles/sec]
|
||||
double Cuc = 11; // Amplitude of the cosine harmonic correction term to the argument of latitude [radians]
|
||||
double Cus = 12; // Amplitude of the sine harmonic correction term to the argument of latitude [radians]
|
||||
double Crc = 13; // Amplitude of the cosine harmonic correction term to the orbit radius [meters]
|
||||
double Crs = 14; // Amplitude of the sine harmonic correction term to the orbit radius [meters]
|
||||
double Cic = 15; // Amplitude of the cosine harmonic correction term to the angle of inclination [radians]
|
||||
double Cis = 16; // Amplitude of the sine harmonic correction term to the angle of inclination [radians]
|
||||
int32 toe = 17; // Ephemeris reference time [s]
|
||||
|
||||
// Clock correction parameters
|
||||
int32 toc = 18; // Clock correction data reference Time of Week [sec]
|
||||
double af0 = 19; // SV clock bias correction coefficient [s]
|
||||
double af1 = 20; // SV clock drift correction coefficient [s/s]
|
||||
double af2 = 21; // SV clock drift rate correction coefficient [s/s^2]
|
||||
|
||||
double satClkDrift = 22; // SV clock drift
|
||||
double dtr = 23; // Relativistic clock correction term
|
||||
|
||||
// Time
|
||||
int32 WN = 24; // Week number
|
||||
int32 tow = 25; // Time of Week
|
||||
|
||||
// Galileo-specific parameters
|
||||
int32 IOD_ephemeris = 26;
|
||||
int32 IOD_nav = 27;
|
||||
|
||||
// SV status
|
||||
int32 SISA = 28; // Signal in space accuracy index
|
||||
int32 E5a_HS = 29; // E5a Signal Health Status
|
||||
int32 E5b_HS = 30; // E5b Signal Health Status
|
||||
int32 E1B_HS = 31; // E1B Signal Health Status
|
||||
bool E5a_DVS = 32; // E5a Data Validity Status
|
||||
bool E5b_DVS = 33; // E5b Data Validity Status
|
||||
bool E1B_DVS = 34; // E1B Data Validity Status
|
||||
double BGD_E1E5a = 35; // E1-E5a Broadcast Group Delay [s]
|
||||
double BGD_E1E5b = 36; // E1-E5b Broadcast Group Delay [s]
|
||||
}
|
57
docs/protobuf/gps_ephemeris.proto
Normal file
57
docs/protobuf/gps_ephemeris.proto
Normal file
@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2018-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es>
|
||||
syntax = "proto3";
|
||||
|
||||
package gnss_sdr;
|
||||
|
||||
message GpsEphemeris {
|
||||
int32 PRN = 1; // SV ID
|
||||
double M_0 = 2; // Mean anomaly at reference time [semi-circles]
|
||||
double delta_n = 3; // Mean motion difference from computed value [semi-circles/sec]
|
||||
double ecc = 4; // Eccentricity
|
||||
double sqrtA = 5; // Square root of the semi-major axis [meters^1/2]
|
||||
double OMEGA_0 = 6; // Longitude of ascending node of orbital plane at weekly epoch [semi-circles]
|
||||
double i_0 = 7; // Inclination angle at reference time [semi-circles]
|
||||
double omega = 8; // Argument of perigee [semi-circles]
|
||||
double OMEGAdot = 9; // Rate of right ascension [semi-circles/sec]
|
||||
double idot = 10; // Rate of inclination angle [semi-circles/sec]
|
||||
double Cuc = 11; // Amplitude of the cosine harmonic correction term to the argument of latitude [radians]
|
||||
double Cus = 12; // Amplitude of the sine harmonic correction term to the argument of latitude [radians]
|
||||
double Crc = 13; // Amplitude of the cosine harmonic correction term to the orbit radius [meters]
|
||||
double Crs = 14; // Amplitude of the sine harmonic correction term to the orbit radius [meters]
|
||||
double Cic = 15; // Amplitude of the cosine harmonic correction term to the angle of inclination [radians]
|
||||
double Cis = 16; // Amplitude of the sine harmonic correction term to the angle of inclination [radians]
|
||||
int32 toe = 17; // Ephemeris reference time [s]
|
||||
|
||||
// Clock correction parameters
|
||||
int32 toc = 18; // Clock correction data reference Time of Week [sec]
|
||||
double af0 = 19; // SV clock bias correction coefficient [s]
|
||||
double af1 = 20; // SV clock drift correction coefficient [s/s]
|
||||
double af2 = 21; // SV clock drift rate correction coefficient [s/s^2]
|
||||
|
||||
double satClkDrift = 22; // SV clock drift
|
||||
double dtr = 23; // Relativistic clock correction term
|
||||
|
||||
// Time
|
||||
int32 WN = 24; // Week number
|
||||
int32 tow = 25; // Time of Week
|
||||
|
||||
// GPS-specific parameters
|
||||
int32 code_on_L2 = 26; // If 1, P code ON in L2; if 2, C/A code ON in L2;
|
||||
bool L2_P_data_flag = 27; // When true, indicates that the NAV data stream was commanded OFF on the P-code of the L2 channel
|
||||
int32 SV_accuracy = 28; // User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200L)
|
||||
int32 SV_health = 29; // Satellite heath status
|
||||
double TGD = 30; // Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s]
|
||||
int32 IODC = 31; // Issue of Data, Clock
|
||||
int32 IODE_SF2 = 32; // Issue of Data, Ephemeris (IODE), subframe 2
|
||||
int32 IODE_SF3 = 33; // Issue of Data, Ephemeris (IODE), subframe 3
|
||||
int32 AODO = 34; // Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s]
|
||||
|
||||
bool fit_interval_flag = 35; // indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours.
|
||||
double spare1 = 36;
|
||||
double spare2 = 37;
|
||||
|
||||
bool integrity_status_flag = 38;
|
||||
bool alert_flag = 39; // If true, indicates that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk.
|
||||
bool antispoofing_flag = 40; // If true, the AntiSpoofing mode is ON in that SV
|
||||
}
|
@ -6,7 +6,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
)
|
||||
|
||||
[comment]: # (
|
||||
SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es>
|
||||
SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es>
|
||||
)
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
@ -33,6 +33,8 @@ elements in an XML document.
|
||||
|
||||
- [cnav_ephemeris_map.xsd](./cnav_ephemeris_map.xsd) - GPS CNAV message
|
||||
ephemeris parameters.
|
||||
- [cnav_utc_model.xsd](./cnav_utc_model.xsd) - GPS CNAV message UTC model
|
||||
parameters.
|
||||
|
||||
## Galileo
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- SPDX-License-Identifier: BSD-3-Clause -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<xs:element name="boost_serialization">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
@ -16,38 +16,46 @@
|
||||
<xs:element name="second">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:byte" name="i_satellite_PRN"/>
|
||||
<xs:element type="xs:int" name="d_TOW"/>
|
||||
<xs:element type="xs:float" name="d_Crs"/>
|
||||
<xs:element type="xs:float" name="d_M_0"/>
|
||||
<xs:element type="xs:float" name="d_Cuc"/>
|
||||
<xs:element type="xs:float" name="d_e_eccentricity"/>
|
||||
<xs:element type="xs:float" name="d_Cus"/>
|
||||
<xs:element type="xs:int" name="d_Toe1"/>
|
||||
<xs:element type="xs:int" name="d_Toe2"/>
|
||||
<xs:element type="xs:byte" name="d_Toc"/>
|
||||
<xs:element type="xs:float" name="d_Cic"/>
|
||||
<xs:element type="xs:float" name="d_OMEGA0"/>
|
||||
<xs:element type="xs:float" name="d_Cis"/>
|
||||
<xs:element type="xs:float" name="d_i_0"/>
|
||||
<xs:element type="xs:float" name="d_Crc"/>
|
||||
<xs:element type="xs:float" name="d_OMEGA"/>
|
||||
<xs:element type="xs:float" name="d_IDOT"/>
|
||||
<xs:element type="xs:short" name="i_GPS_week"/>
|
||||
<xs:element type="xs:float" name="d_TGD"/>
|
||||
<xs:element type="xs:float" name="d_ISCL1"/>
|
||||
<xs:element type="xs:float" name="d_ISCL2"/>
|
||||
<xs:element type="xs:float" name="d_ISCL5I"/>
|
||||
<xs:element type="xs:float" name="d_ISCL5Q"/>
|
||||
<xs:element type="xs:float" name="d_DELTA_A"/>
|
||||
<xs:element type="xs:float" name="d_A_DOT"/>
|
||||
<xs:element type="xs:float" name="d_DELTA_OMEGA_DOT"/>
|
||||
<xs:element type="xs:float" name="d_A_f0"/>
|
||||
<xs:element type="xs:float" name="d_A_f1"/>
|
||||
<xs:element type="xs:float" name="d_A_f2"/>
|
||||
<xs:element type="xs:byte" name="b_integrity_status_flag"/>
|
||||
<xs:element type="xs:byte" name="b_alert_flag"/>
|
||||
<xs:element type="xs:byte" name="b_antispoofing_flag"/>
|
||||
<xs:element type="xs:byte" name="PRN"/>
|
||||
<xs:element type="xs:float" name="M_0"/>
|
||||
<xs:element type="xs:float" name="delta_n"/>
|
||||
<xs:element type="xs:float" name="ecc"/>
|
||||
<xs:element type="xs:float" name="sqrtA"/>
|
||||
<xs:element type="xs:float" name="OMEGA_0"/>
|
||||
<xs:element type="xs:float" name="i_0"/>
|
||||
<xs:element type="xs:float" name="omega"/>
|
||||
<xs:element type="xs:float" name="OMEGAdot"/>
|
||||
<xs:element type="xs:float" name="idot"/>
|
||||
<xs:element type="xs:float" name="Cuc"/>
|
||||
<xs:element type="xs:float" name="Cus"/>
|
||||
<xs:element type="xs:float" name="Crc"/>
|
||||
<xs:element type="xs:float" name="Crs"/>
|
||||
<xs:element type="xs:float" name="Cic"/>
|
||||
<xs:element type="xs:float" name="Cis"/>
|
||||
<xs:element type="xs:int" name="toe"/>
|
||||
<xs:element type="xs:int" name="toc"/>
|
||||
<xs:element type="xs:float" name="af0"/>
|
||||
<xs:element type="xs:float" name="af1"/>
|
||||
<xs:element type="xs:float" name="af2"/>
|
||||
<xs:element type="xs:short" name="WN"/>
|
||||
<xs:element type="xs:int" name="tow"/>
|
||||
<xs:element type="xs:float" name="satClkDrift"/>
|
||||
<xs:element type="xs:float" name="dtr"/>
|
||||
<xs:element type="xs:byte" name="IODE_SF2"/>
|
||||
<xs:element type="xs:byte" name="IODE_SF3"/>
|
||||
<xs:element type="xs:byte" name="code_on_L2"/>
|
||||
<xs:element type="xs:byte" name="L2_P_data_flag"/>
|
||||
<xs:element type="xs:byte" name="SV_accuracy"/>
|
||||
<xs:element type="xs:byte" name="SV_health"/>
|
||||
<xs:element type="xs:float" name="TGD"/>
|
||||
<xs:element type="xs:byte" name="IODC"/>
|
||||
<xs:element type="xs:short" name="AODO"/>
|
||||
<xs:element type="xs:byte" name="fit_interval_flag"/>
|
||||
<xs:element type="xs:float" name="spare1"/>
|
||||
<xs:element type="xs:float" name="spare2"/>
|
||||
<xs:element type="xs:byte" name="integrity_status_flag"/>
|
||||
<xs:element type="xs:byte" name="alert_flag"/>
|
||||
<xs:element type="xs:byte" name="antispoofing_flag"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:byte" name="class_id" use="optional"/>
|
||||
<xs:attribute type="xs:byte" name="tracking_level" use="optional"/>
|
||||
|
31
docs/xml-schemas/cnav_utc_model.xsd
Normal file
31
docs/xml-schemas/cnav_utc_model.xsd
Normal file
@ -0,0 +1,31 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- SPDX-License-Identifier: BSD-3-Clause -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<xs:element name="boost_serialization">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="GNSS-SDR_cnav_utc_model">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:float" name="A0"/>
|
||||
<xs:element type="xs:float" name="A1"/>
|
||||
<xs:element type="xs:float" name="A2"/>
|
||||
<xs:element type="xs:int" name="tot"/>
|
||||
<xs:element type="xs:short" name="WN_T"/>
|
||||
<xs:element type="xs:byte" name="DeltaT_LS"/>
|
||||
<xs:element type="xs:short" name="WN_LSF"/>
|
||||
<xs:element type="xs:byte" name="DN"/>
|
||||
<xs:element type="xs:byte" name="DeltaT_LSF"/>
|
||||
<xs:element type="xs:byte" name="valid"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:byte" name="class_id"/>
|
||||
<xs:attribute type="xs:byte" name="tracking_level"/>
|
||||
<xs:attribute type="xs:byte" name="version"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:string" name="signature"/>
|
||||
<xs:attribute type="xs:byte" name="version"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
@ -1,6 +1,6 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
IODE_SF<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- SPDX-License-Identifier: BSD-3-Clause -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<xs:element name="boost_serialization">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
@ -16,44 +16,44 @@
|
||||
<xs:element name="second">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:byte" name="i_satellite_PRN"/>
|
||||
<xs:element type="xs:int" name="d_TOW"/>
|
||||
<xs:element type="xs:byte" name="d_IODE_SF2"/>
|
||||
<xs:element type="xs:byte" name="d_IODE_SF3"/>
|
||||
<xs:element type="xs:float" name="d_Crs"/>
|
||||
<xs:element type="xs:float" name="d_Delta_n"/>
|
||||
<xs:element type="xs:float" name="d_M_0"/>
|
||||
<xs:element type="xs:float" name="d_Cuc"/>
|
||||
<xs:element type="xs:float" name="d_e_eccentricity"/>
|
||||
<xs:element type="xs:float" name="d_Cus"/>
|
||||
<xs:element type="xs:float" name="d_sqrt_A"/>
|
||||
<xs:element type="xs:int" name="d_Toe"/>
|
||||
<xs:element type="xs:int" name="d_Toc"/>
|
||||
<xs:element type="xs:float" name="d_Cic"/>
|
||||
<xs:element type="xs:float" name="d_OMEGA0"/>
|
||||
<xs:element type="xs:float" name="d_Cis"/>
|
||||
<xs:element type="xs:float" name="d_i_0"/>
|
||||
<xs:element type="xs:float" name="d_Crc"/>
|
||||
<xs:element type="xs:float" name="d_OMEGA"/>
|
||||
<xs:element type="xs:float" name="d_OMEGA_DOT"/>
|
||||
<xs:element type="xs:float" name="d_IDOT"/>
|
||||
<xs:element type="xs:byte" name="i_code_on_L2"/>
|
||||
<xs:element type="xs:short" name="i_GPS_week"/>
|
||||
<xs:element type="xs:byte" name="b_L2_P_data_flag"/>
|
||||
<xs:element type="xs:byte" name="i_SV_accuracy"/>
|
||||
<xs:element type="xs:byte" name="i_SV_health"/>
|
||||
<xs:element type="xs:float" name="d_TGD"/>
|
||||
<xs:element type="xs:byte" name="d_IODC"/>
|
||||
<xs:element type="xs:short" name="i_AODO"/>
|
||||
<xs:element type="xs:byte" name="b_fit_interval_flag"/>
|
||||
<xs:element type="xs:float" name="d_spare1"/>
|
||||
<xs:element type="xs:float" name="d_spare2"/>
|
||||
<xs:element type="xs:float" name="d_A_f0"/>
|
||||
<xs:element type="xs:float" name="d_A_f1"/>
|
||||
<xs:element type="xs:float" name="d_A_f2"/>
|
||||
<xs:element type="xs:byte" name="b_integrity_status_flag"/>
|
||||
<xs:element type="xs:byte" name="b_alert_flag"/>
|
||||
<xs:element type="xs:byte" name="b_antispoofing_flag"/>
|
||||
<xs:element type="xs:byte" name="PRN"/>
|
||||
<xs:element type="xs:int" name="tow"/>
|
||||
<xs:element type="xs:byte" name="IODE_SF2"/>
|
||||
<xs:element type="xs:byte" name="IODE_SF3"/>
|
||||
<xs:element type="xs:float" name="Crs"/>
|
||||
<xs:element type="xs:float" name="delta_n"/>
|
||||
<xs:element type="xs:float" name="M_0"/>
|
||||
<xs:element type="xs:float" name="Cuc"/>
|
||||
<xs:element type="xs:float" name="ecc"/>
|
||||
<xs:element type="xs:float" name="Cus"/>
|
||||
<xs:element type="xs:float" name="sqrtA"/>
|
||||
<xs:element type="xs:int" name="toe"/>
|
||||
<xs:element type="xs:int" name="toc"/>
|
||||
<xs:element type="xs:float" name="Cic"/>
|
||||
<xs:element type="xs:float" name="OMEGA_0"/>
|
||||
<xs:element type="xs:float" name="Cis"/>
|
||||
<xs:element type="xs:float" name="i_0"/>
|
||||
<xs:element type="xs:float" name="Crc"/>
|
||||
<xs:element type="xs:float" name="omega"/>
|
||||
<xs:element type="xs:float" name="OMEGAdot"/>
|
||||
<xs:element type="xs:float" name="idot"/>
|
||||
<xs:element type="xs:byte" name="code_on_L2"/>
|
||||
<xs:element type="xs:short" name="WN"/>
|
||||
<xs:element type="xs:byte" name="L2_P_data_flag"/>
|
||||
<xs:element type="xs:byte" name="SV_accuracy"/>
|
||||
<xs:element type="xs:byte" name="SV_health"/>
|
||||
<xs:element type="xs:float" name="TGD"/>
|
||||
<xs:element type="xs:byte" name="IODC"/>
|
||||
<xs:element type="xs:short" name="AODO"/>
|
||||
<xs:element type="xs:byte" name="fit_interval_flag"/>
|
||||
<xs:element type="xs:float" name="spare1"/>
|
||||
<xs:element type="xs:float" name="spare2"/>
|
||||
<xs:element type="xs:float" name="af0"/>
|
||||
<xs:element type="xs:float" name="af1"/>
|
||||
<xs:element type="xs:float" name="af2"/>
|
||||
<xs:element type="xs:byte" name="integrity_status_flag"/>
|
||||
<xs:element type="xs:byte" name="alert_flag"/>
|
||||
<xs:element type="xs:byte" name="antispoofing_flag"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:byte" name="class_id" use="optional"/>
|
||||
<xs:attribute type="xs:byte" name="tracking_level" use="optional"/>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- SPDX-License-Identifier: BSD-3-Clause -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<xs:element name="boost_serialization">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
@ -16,19 +16,19 @@
|
||||
<xs:element name="second">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:byte" name="i_satellite_PRN"/>
|
||||
<xs:element type="xs:int" name="i_Toa"/>
|
||||
<xs:element type="xs:byte" name="i_WNa"/>
|
||||
<xs:element type="xs:byte" name="i_IODa"/>
|
||||
<xs:element type="xs:float" name="d_Delta_i"/>
|
||||
<xs:element type="xs:float" name="d_M_0"/>
|
||||
<xs:element type="xs:float" name="d_e_eccentricity"/>
|
||||
<xs:element type="xs:float" name="d_Delta_sqrt_A"/>
|
||||
<xs:element type="xs:float" name="d_OMEGA0"/>
|
||||
<xs:element type="xs:float" name="d_OMEGA"/>
|
||||
<xs:element type="xs:float" name="d_OMEGA_DOT"/>
|
||||
<xs:element type="xs:float" name="d_A_f0"/>
|
||||
<xs:element type="xs:float" name="d_A_f1"/>
|
||||
<xs:element type="xs:byte" name="PRN"/>
|
||||
<xs:element type="xs:int" name="toa"/>
|
||||
<xs:element type="xs:byte" name="WNa"/>
|
||||
<xs:element type="xs:byte" name="IODa"/>
|
||||
<xs:element type="xs:float" name="delta_i"/>
|
||||
<xs:element type="xs:float" name="M_0"/>
|
||||
<xs:element type="xs:float" name="ecc"/>
|
||||
<xs:element type="xs:float" name="delta_sqrtA"/>
|
||||
<xs:element type="xs:float" name="OMEGA_0"/>
|
||||
<xs:element type="xs:float" name="omega"/>
|
||||
<xs:element type="xs:float" name="OMEGAdot"/>
|
||||
<xs:element type="xs:float" name="af0"/>
|
||||
<xs:element type="xs:float" name="af1"/>
|
||||
<xs:element type="xs:byte" name="E5b_HS"/>
|
||||
<xs:element type="xs:byte" name="E1B_HS"/>
|
||||
<xs:element type="xs:byte" name="E5a_HS"/>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- SPDX-License-Identifier: BSD-3-Clause -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<xs:element name="boost_serialization">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
@ -16,43 +16,42 @@
|
||||
<xs:element name="second">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:byte" name="i_satellite_PRN"/>
|
||||
<xs:element type="xs:float" name="M0_1"/>
|
||||
<xs:element type="xs:float" name="delta_n_3"/>
|
||||
<xs:element type="xs:float" name="e_1"/>
|
||||
<xs:element type="xs:float" name="A_1"/>
|
||||
<xs:element type="xs:float" name="OMEGA_0_2"/>
|
||||
<xs:element type="xs:float" name="i_0_2"/>
|
||||
<xs:element type="xs:float" name="omega_2"/>
|
||||
<xs:element type="xs:float" name="OMEGA_dot_3"/>
|
||||
<xs:element type="xs:float" name="iDot_2"/>
|
||||
<xs:element type="xs:float" name="C_uc_3"/>
|
||||
<xs:element type="xs:float" name="C_us_3"/>
|
||||
<xs:element type="xs:float" name="C_rc_3"/>
|
||||
<xs:element type="xs:float" name="C_rs_3"/>
|
||||
<xs:element type="xs:float" name="C_ic_4"/>
|
||||
<xs:element type="xs:float" name="C_is_4"/>
|
||||
<xs:element type="xs:int" name="t0e_1"/>
|
||||
<xs:element type="xs:int" name="t0c_4"/>
|
||||
<xs:element type="xs:float" name="af0_4"/>
|
||||
<xs:element type="xs:float" name="af1_4"/>
|
||||
<xs:element type="xs:float" name="af2_4"/>
|
||||
<xs:element type="xs:short" name="WN_5"/>
|
||||
<xs:element type="xs:int" name="TOW_5"/>
|
||||
<xs:element type="xs:float" name="Galileo_satClkDrift"/>
|
||||
<xs:element type="xs:float" name="Galileo_dtr"/>
|
||||
|
||||
<xs:element type="xs:byte" name="PRN"/>
|
||||
<xs:element type="xs:float" name="M_0"/>
|
||||
<xs:element type="xs:float" name="delta_n"/>
|
||||
<xs:element type="xs:float" name="ecc"/>
|
||||
<xs:element type="xs:float" name="sqrtA"/>
|
||||
<xs:element type="xs:float" name="OMEGA_0"/>
|
||||
<xs:element type="xs:float" name="i_0"/>
|
||||
<xs:element type="xs:float" name="omega"/>
|
||||
<xs:element type="xs:float" name="OMEGAdot"/>
|
||||
<xs:element type="xs:float" name="idot"/>
|
||||
<xs:element type="xs:float" name="Cuc"/>
|
||||
<xs:element type="xs:float" name="Cus"/>
|
||||
<xs:element type="xs:float" name="Crc"/>
|
||||
<xs:element type="xs:float" name="Crs"/>
|
||||
<xs:element type="xs:float" name="Cic"/>
|
||||
<xs:element type="xs:float" name="Cis"/>
|
||||
<xs:element type="xs:int" name="toe"/>
|
||||
<xs:element type="xs:int" name="toc"/>
|
||||
<xs:element type="xs:float" name="af0"/>
|
||||
<xs:element type="xs:float" name="af1"/>
|
||||
<xs:element type="xs:float" name="af2"/>
|
||||
<xs:element type="xs:short" name="WN"/>
|
||||
<xs:element type="xs:int" name="tow"/>
|
||||
<xs:element type="xs:float" name="satClkDrift"/>
|
||||
<xs:element type="xs:float" name="dtr"/>
|
||||
<xs:element type="xs:byte" name="IOD_ephemeris"/>
|
||||
<xs:element type="xs:byte" name="IOD_nav_1"/>
|
||||
<xs:element type="xs:byte" name="SISA_3"/>
|
||||
<xs:element type="xs:byte" name="IOD_nav"/>
|
||||
<xs:element type="xs:byte" name="SISA"/>
|
||||
<xs:element type="xs:byte" name="E5a_HS"/>
|
||||
<xs:element type="xs:byte" name="E5b_HS_5"/>
|
||||
<xs:element type="xs:byte" name="E1B_HS_5"/>
|
||||
<xs:element type="xs:byte" name="E5b_HS"/>
|
||||
<xs:element type="xs:byte" name="E1B_HS"/>
|
||||
<xs:element type="xs:byte" name="E5a_DVS"/>
|
||||
<xs:element type="xs:byte" name="E5b_DVS_5"/>
|
||||
<xs:element type="xs:byte" name="E1B_DVS_5"/>
|
||||
<xs:element type="xs:float" name="BGD_E1E5a_5"/>
|
||||
<xs:element type="xs:float" name="BGD_E1E5b_5"/>
|
||||
<xs:element type="xs:byte" name="E5b_DVS"/>
|
||||
<xs:element type="xs:byte" name="E1B_DVS"/>
|
||||
<xs:element type="xs:float" name="BGD_E1E5a"/>
|
||||
<xs:element type="xs:float" name="BGD_E1E5b"/>
|
||||
<xs:element type="xs:byte" name="flag_all_ephemeris"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:byte" name="class_id" use="optional"/>
|
||||
|
@ -1,22 +1,22 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- SPDX-License-Identifier: BSD-3-Clause -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<xs:element name="boost_serialization">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="GNSS-SDR_gal_iono_model">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:float" name="ai0_5"/>
|
||||
<xs:element type="xs:float" name="ai1_5"/>
|
||||
<xs:element type="xs:float" name="ai2_5"/>
|
||||
<xs:element type="xs:int" name="TOW_5"/>
|
||||
<xs:element type="xs:short" name="WN_5"/>
|
||||
<xs:element type="xs:byte" name="Region1_flag_5"/>
|
||||
<xs:element type="xs:byte" name="Region2_flag_5"/>
|
||||
<xs:element type="xs:byte" name="Region3_flag_5"/>
|
||||
<xs:element type="xs:byte" name="Region4_flag_5"/>
|
||||
<xs:element type="xs:byte" name="Region5_flag_5"/>
|
||||
<xs:element type="xs:float" name="ai0"/>
|
||||
<xs:element type="xs:float" name="ai1"/>
|
||||
<xs:element type="xs:float" name="ai2"/>
|
||||
<xs:element type="xs:int" name="tow"/>
|
||||
<xs:element type="xs:short" name="WN"/>
|
||||
<xs:element type="xs:byte" name="Region1_flag"/>
|
||||
<xs:element type="xs:byte" name="Region2_flag"/>
|
||||
<xs:element type="xs:byte" name="Region3_flag"/>
|
||||
<xs:element type="xs:byte" name="Region4_flag"/>
|
||||
<xs:element type="xs:byte" name="Region5_flag"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:byte" name="class_id"/>
|
||||
<xs:attribute type="xs:byte" name="tracking_level"/>
|
||||
|
@ -1,20 +1,20 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- SPDX-License-Identifier: BSD-3-Clause -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<xs:element name="boost_serialization">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="GNSS-SDR_gal_utc_model">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:float" name="A0_6"/>
|
||||
<xs:element type="xs:float" name="A1_6"/>
|
||||
<xs:element type="xs:byte" name="Delta_tLS_6"/>
|
||||
<xs:element type="xs:int" name="t0t_6"/>
|
||||
<xs:element type="xs:short" name="WNot_6"/>
|
||||
<xs:element type="xs:short" name="WN_LSF_6"/>
|
||||
<xs:element type="xs:byte" name="DN_6"/>
|
||||
<xs:element type="xs:byte" name="Delta_tLSF_6"/>
|
||||
<xs:element type="xs:float" name="A0"/>
|
||||
<xs:element type="xs:float" name="A1"/>
|
||||
<xs:element type="xs:byte" name="Delta_tLS"/>
|
||||
<xs:element type="xs:int" name="tot"/>
|
||||
<xs:element type="xs:short" name="WNot"/>
|
||||
<xs:element type="xs:short" name="WN_LSF"/>
|
||||
<xs:element type="xs:byte" name="DN"/>
|
||||
<xs:element type="xs:byte" name="Delta_tLSF"/>
|
||||
<xs:element type="xs:byte" name="flag_utc_model"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:byte" name="class_id"/>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- SPDX-License-Identifier: BSD-3-Clause -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<xs:element name="boost_serialization">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
@ -16,20 +16,20 @@
|
||||
<xs:element name="second">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:byte" name="i_satellite_PRN"/>
|
||||
<xs:element type="xs:float" name="d_Delta_i"/>
|
||||
<xs:element type="xs:byte" name="i_Toa"/>
|
||||
<xs:element type="xs:byte" name="i_WNa"/>
|
||||
<xs:element type="xs:float" name="d_M_0"/>
|
||||
<xs:element type="xs:float" name="d_e_eccentricity"/>
|
||||
<xs:element type="xs:float" name="d_sqrt_A"/>
|
||||
<xs:element type="xs:float" name="d_OMEGA0"/>
|
||||
<xs:element type="xs:float" name="d_OMEGA"/>
|
||||
<xs:element type="xs:float" name="d_OMEGA_DOT"/>
|
||||
<xs:element type="xs:byte" name="i_SV_health"/>
|
||||
<xs:element type="xs:byte" name="i_AS_status"/>
|
||||
<xs:element type="xs:float" name="d_A_f0"/>
|
||||
<xs:element type="xs:float" name="d_A_f1"/>
|
||||
<xs:element type="xs:byte" name="PRN"/>
|
||||
<xs:element type="xs:float" name="delta_i"/>
|
||||
<xs:element type="xs:byte" name="toa"/>
|
||||
<xs:element type="xs:byte" name="WNa"/>
|
||||
<xs:element type="xs:float" name="M_0"/>
|
||||
<xs:element type="xs:float" name="ecc"/>
|
||||
<xs:element type="xs:float" name="sqrtA"/>
|
||||
<xs:element type="xs:float" name="OMEGA_0"/>
|
||||
<xs:element type="xs:float" name="omega"/>
|
||||
<xs:element type="xs:float" name="OMEGAdot"/>
|
||||
<xs:element type="xs:byte" name="SV_health"/>
|
||||
<xs:element type="xs:byte" name="AS_status"/>
|
||||
<xs:element type="xs:float" name="af0"/>
|
||||
<xs:element type="xs:float" name="af1"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:byte" name="class_id" use="optional"/>
|
||||
<xs:attribute type="xs:byte" name="tracking_level" use="optional"/>
|
||||
|
@ -1,20 +1,20 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- SPDX-License-Identifier: BSD-3-Clause -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<xs:element name="boost_serialization">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="GNSS-SDR_iono_model">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:float" name="d_alpha0"/>
|
||||
<xs:element type="xs:float" name="d_alpha1"/>
|
||||
<xs:element type="xs:float" name="d_alpha2"/>
|
||||
<xs:element type="xs:float" name="d_alpha3"/>
|
||||
<xs:element type="xs:float" name="d_beta0"/>
|
||||
<xs:element type="xs:float" name="d_beta1"/>
|
||||
<xs:element type="xs:float" name="d_beta2"/>
|
||||
<xs:element type="xs:float" name="d_beta3"/>
|
||||
<xs:element type="xs:float" name="alpha0"/>
|
||||
<xs:element type="xs:float" name="alpha1"/>
|
||||
<xs:element type="xs:float" name="alpha2"/>
|
||||
<xs:element type="xs:float" name="alpha3"/>
|
||||
<xs:element type="xs:float" name="beta0"/>
|
||||
<xs:element type="xs:float" name="beta1"/>
|
||||
<xs:element type="xs:float" name="beta2"/>
|
||||
<xs:element type="xs:float" name="beta3"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:byte" name="class_id"/>
|
||||
<xs:attribute type="xs:byte" name="tracking_level"/>
|
||||
|
@ -1,20 +1,21 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- SPDX-License-Identifier: BSD-3-Clause -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<!-- SPDX-FileCopyrightText: 2018-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es> -->
|
||||
<xs:element name="boost_serialization">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="GNSS-SDR_utc_model">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:float" name="d_A1"/>
|
||||
<xs:element type="xs:float" name="d_A0"/>
|
||||
<xs:element type="xs:int" name="d_t_OT"/>
|
||||
<xs:element type="xs:short" name="i_WN_T"/>
|
||||
<xs:element type="xs:byte" name="d_DeltaT_LS"/>
|
||||
<xs:element type="xs:short" name="i_WN_LSF"/>
|
||||
<xs:element type="xs:byte" name="i_DN"/>
|
||||
<xs:element type="xs:byte" name="d_DeltaT_LSF"/>
|
||||
<xs:element type="xs:float" name="A0"/>
|
||||
<xs:element type="xs:float" name="A1"/>
|
||||
<xs:element type="xs:float" name="A2"/>
|
||||
<xs:element type="xs:int" name="tot"/>
|
||||
<xs:element type="xs:short" name="WN_T"/>
|
||||
<xs:element type="xs:byte" name="DeltaT_LS"/>
|
||||
<xs:element type="xs:short" name="WN_LSF"/>
|
||||
<xs:element type="xs:byte" name="DN"/>
|
||||
<xs:element type="xs:byte" name="DeltaT_LSF"/>
|
||||
<xs:element type="xs:byte" name="valid"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:byte" name="class_id"/>
|
||||
|
@ -804,6 +804,11 @@ Rtklib_Pvt::Rtklib_Pvt(const ConfigurationInterface* configuration,
|
||||
pvt_output_parameters.protobuf_enabled = true;
|
||||
}
|
||||
|
||||
// Read EPHEMERIS MONITOR Configuration
|
||||
pvt_output_parameters.monitor_ephemeris_enabled = configuration->property(role + ".enable_monitor_ephemeris", false);
|
||||
pvt_output_parameters.udp_eph_addresses = configuration->property(role + ".monitor_ephemeris_client_addresses", std::string("127.0.0.1"));
|
||||
pvt_output_parameters.udp_eph_port = configuration->property(role + ".monitor_ephemeris_udp_port", 1234);
|
||||
|
||||
// Show time in local zone
|
||||
pvt_output_parameters.show_local_time_zone = configuration->property(role + ".show_local_time_zone", false);
|
||||
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "gps_utc_model.h"
|
||||
#include "gpx_printer.h"
|
||||
#include "kml_printer.h"
|
||||
#include "monitor_ephemeris_udp_sink.h"
|
||||
#include "monitor_pvt.h"
|
||||
#include "monitor_pvt_udp_sink.h"
|
||||
#include "nmea_printer.h"
|
||||
@ -399,6 +400,22 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
|
||||
d_udp_sink_ptr = nullptr;
|
||||
}
|
||||
|
||||
// EPHEMERIS MONITOR
|
||||
d_flag_monitor_ephemeris_enabled = conf_.monitor_ephemeris_enabled;
|
||||
if (d_flag_monitor_ephemeris_enabled)
|
||||
{
|
||||
std::string address_string = conf_.udp_eph_addresses;
|
||||
std::vector<std::string> udp_addr_vec = split_string(address_string, '_');
|
||||
std::sort(udp_addr_vec.begin(), udp_addr_vec.end());
|
||||
udp_addr_vec.erase(std::unique(udp_addr_vec.begin(), udp_addr_vec.end()), udp_addr_vec.end());
|
||||
|
||||
d_eph_udp_sink_ptr = std::make_unique<Monitor_Ephemeris_Udp_Sink>(udp_addr_vec, conf_.udp_eph_port, conf_.protobuf_enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
d_eph_udp_sink_ptr = nullptr;
|
||||
}
|
||||
|
||||
// Create Sys V message queue
|
||||
d_first_fix = true;
|
||||
d_sysv_msg_key = 1101;
|
||||
@ -653,7 +670,7 @@ rtklib_pvt_gs::~rtklib_pvt_gs()
|
||||
|
||||
// Save Galileo UTC model parameters
|
||||
file_name = d_xml_base_path + "gal_utc_model.xml";
|
||||
if (d_internal_pvt_solver->galileo_utc_model.Delta_tLS_6 != 0.0)
|
||||
if (d_internal_pvt_solver->galileo_utc_model.Delta_tLS != 0.0)
|
||||
{
|
||||
std::ofstream ofs;
|
||||
try
|
||||
@ -743,7 +760,7 @@ rtklib_pvt_gs::~rtklib_pvt_gs()
|
||||
|
||||
// Save Galileo iono parameters
|
||||
file_name = d_xml_base_path + "gal_iono.xml";
|
||||
if (d_internal_pvt_solver->galileo_iono.ai0_5 != 0.0)
|
||||
if (d_internal_pvt_solver->galileo_iono.ai0 != 0.0)
|
||||
{
|
||||
std::ofstream ofs;
|
||||
try
|
||||
@ -1060,21 +1077,28 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
// ### GPS EPHEMERIS ###
|
||||
const auto gps_eph = boost::any_cast<std::shared_ptr<Gps_Ephemeris>>(pmt::any_ref(msg));
|
||||
DLOG(INFO) << "Ephemeris record has arrived from SAT ID "
|
||||
<< gps_eph->i_satellite_PRN << " (Block "
|
||||
<< gps_eph->satelliteBlock[gps_eph->i_satellite_PRN] << ")"
|
||||
<< "inserted with Toe=" << gps_eph->d_Toe << " and GPS Week="
|
||||
<< gps_eph->i_GPS_week;
|
||||
<< gps_eph->PRN << " (Block "
|
||||
<< gps_eph->satelliteBlock[gps_eph->PRN] << ")"
|
||||
<< "inserted with Toe=" << gps_eph->toe << " and GPS Week="
|
||||
<< gps_eph->WN;
|
||||
|
||||
// todo: Send only new sets of ephemeris (new TOE), not sent to the client
|
||||
// send the new eph to the eph monitor (if enabled)
|
||||
if (d_flag_monitor_ephemeris_enabled)
|
||||
{
|
||||
d_eph_udp_sink_ptr->write_gps_ephemeris(gps_eph);
|
||||
}
|
||||
// update/insert new ephemeris record to the global ephemeris map
|
||||
if (d_rp->is_rinex_header_written()) // The header is already written, we can now log the navigation message data
|
||||
if (d_rinex_output_enabled && d_rp->is_rinex_header_written()) // The header is already written, we can now log the navigation message data
|
||||
{
|
||||
bool new_annotation = false;
|
||||
if (d_internal_pvt_solver->gps_ephemeris_map.find(gps_eph->i_satellite_PRN) == d_internal_pvt_solver->gps_ephemeris_map.cend())
|
||||
if (d_internal_pvt_solver->gps_ephemeris_map.find(gps_eph->PRN) == d_internal_pvt_solver->gps_ephemeris_map.cend())
|
||||
{
|
||||
new_annotation = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d_internal_pvt_solver->gps_ephemeris_map[gps_eph->i_satellite_PRN].d_Toe != gps_eph->d_Toe)
|
||||
if (d_internal_pvt_solver->gps_ephemeris_map[gps_eph->PRN].toe != gps_eph->toe)
|
||||
{
|
||||
new_annotation = true;
|
||||
}
|
||||
@ -1083,14 +1107,14 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
{
|
||||
// New record!
|
||||
std::map<int32_t, Gps_Ephemeris> new_eph;
|
||||
new_eph[gps_eph->i_satellite_PRN] = *gps_eph;
|
||||
new_eph[gps_eph->PRN] = *gps_eph;
|
||||
d_rp->log_rinex_nav_gps_nav(d_type_of_rx, new_eph);
|
||||
}
|
||||
}
|
||||
d_internal_pvt_solver->gps_ephemeris_map[gps_eph->i_satellite_PRN] = *gps_eph;
|
||||
d_internal_pvt_solver->gps_ephemeris_map[gps_eph->PRN] = *gps_eph;
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
d_user_pvt_solver->gps_ephemeris_map[gps_eph->i_satellite_PRN] = *gps_eph;
|
||||
d_user_pvt_solver->gps_ephemeris_map[gps_eph->PRN] = *gps_eph;
|
||||
}
|
||||
}
|
||||
else if (msg_type_hash_code == d_gps_iono_sptr_type_hash_code)
|
||||
@ -1120,16 +1144,16 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
// ### GPS CNAV message ###
|
||||
const auto gps_cnav_ephemeris = boost::any_cast<std::shared_ptr<Gps_CNAV_Ephemeris>>(pmt::any_ref(msg));
|
||||
// update/insert new ephemeris record to the global ephemeris map
|
||||
if (d_rp->is_rinex_header_written()) // The header is already written, we can now log the navigation message data
|
||||
if (d_rinex_output_enabled && d_rp->is_rinex_header_written()) // The header is already written, we can now log the navigation message data
|
||||
{
|
||||
bool new_annotation = false;
|
||||
if (d_internal_pvt_solver->gps_cnav_ephemeris_map.find(gps_cnav_ephemeris->i_satellite_PRN) == d_internal_pvt_solver->gps_cnav_ephemeris_map.cend())
|
||||
if (d_internal_pvt_solver->gps_cnav_ephemeris_map.find(gps_cnav_ephemeris->PRN) == d_internal_pvt_solver->gps_cnav_ephemeris_map.cend())
|
||||
{
|
||||
new_annotation = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d_internal_pvt_solver->gps_cnav_ephemeris_map[gps_cnav_ephemeris->i_satellite_PRN].d_Toe1 != gps_cnav_ephemeris->d_Toe1)
|
||||
if (d_internal_pvt_solver->gps_cnav_ephemeris_map[gps_cnav_ephemeris->PRN].toe1 != gps_cnav_ephemeris->toe1)
|
||||
{
|
||||
new_annotation = true;
|
||||
}
|
||||
@ -1138,14 +1162,14 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
{
|
||||
// New record!
|
||||
std::map<int32_t, Gps_CNAV_Ephemeris> new_cnav_eph;
|
||||
new_cnav_eph[gps_cnav_ephemeris->i_satellite_PRN] = *gps_cnav_ephemeris;
|
||||
new_cnav_eph[gps_cnav_ephemeris->PRN] = *gps_cnav_ephemeris;
|
||||
d_rp->log_rinex_nav_gps_cnav(d_type_of_rx, new_cnav_eph);
|
||||
}
|
||||
}
|
||||
d_internal_pvt_solver->gps_cnav_ephemeris_map[gps_cnav_ephemeris->i_satellite_PRN] = *gps_cnav_ephemeris;
|
||||
d_internal_pvt_solver->gps_cnav_ephemeris_map[gps_cnav_ephemeris->PRN] = *gps_cnav_ephemeris;
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
d_user_pvt_solver->gps_cnav_ephemeris_map[gps_cnav_ephemeris->i_satellite_PRN] = *gps_cnav_ephemeris;
|
||||
d_user_pvt_solver->gps_cnav_ephemeris_map[gps_cnav_ephemeris->PRN] = *gps_cnav_ephemeris;
|
||||
}
|
||||
DLOG(INFO) << "New GPS CNAV ephemeris record has arrived ";
|
||||
}
|
||||
@ -1175,10 +1199,10 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
{
|
||||
// ### GPS ALMANAC ###
|
||||
const auto gps_almanac = boost::any_cast<std::shared_ptr<Gps_Almanac>>(pmt::any_ref(msg));
|
||||
d_internal_pvt_solver->gps_almanac_map[gps_almanac->i_satellite_PRN] = *gps_almanac;
|
||||
d_internal_pvt_solver->gps_almanac_map[gps_almanac->PRN] = *gps_almanac;
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
d_user_pvt_solver->gps_almanac_map[gps_almanac->i_satellite_PRN] = *gps_almanac;
|
||||
d_user_pvt_solver->gps_almanac_map[gps_almanac->PRN] = *gps_almanac;
|
||||
}
|
||||
DLOG(INFO) << "New GPS almanac record has arrived ";
|
||||
}
|
||||
@ -1189,20 +1213,26 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
// ### Galileo EPHEMERIS ###
|
||||
const auto galileo_eph = boost::any_cast<std::shared_ptr<Galileo_Ephemeris>>(pmt::any_ref(msg));
|
||||
// insert new ephemeris record
|
||||
DLOG(INFO) << "Galileo New Ephemeris record inserted in global map with TOW =" << galileo_eph->TOW_5
|
||||
<< ", GALILEO Week Number =" << galileo_eph->WN_5
|
||||
DLOG(INFO) << "Galileo New Ephemeris record inserted in global map with TOW =" << galileo_eph->tow
|
||||
<< ", GALILEO Week Number =" << galileo_eph->WN
|
||||
<< " and Ephemeris IOD = " << galileo_eph->IOD_ephemeris;
|
||||
// todo: Send only new sets of ephemeris (new TOE), not sent to the client
|
||||
// send the new eph to the eph monitor (if enabled)
|
||||
if (d_flag_monitor_ephemeris_enabled)
|
||||
{
|
||||
d_eph_udp_sink_ptr->write_galileo_ephemeris(galileo_eph);
|
||||
}
|
||||
// update/insert new ephemeris record to the global ephemeris map
|
||||
if (d_rp->is_rinex_header_written()) // The header is already written, we can now log the navigation message data
|
||||
if (d_rinex_output_enabled && d_rp->is_rinex_header_written()) // The header is already written, we can now log the navigation message data
|
||||
{
|
||||
bool new_annotation = false;
|
||||
if (d_internal_pvt_solver->galileo_ephemeris_map.find(galileo_eph->i_satellite_PRN) == d_internal_pvt_solver->galileo_ephemeris_map.cend())
|
||||
if (d_internal_pvt_solver->galileo_ephemeris_map.find(galileo_eph->PRN) == d_internal_pvt_solver->galileo_ephemeris_map.cend())
|
||||
{
|
||||
new_annotation = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d_internal_pvt_solver->galileo_ephemeris_map[galileo_eph->i_satellite_PRN].t0e_1 != galileo_eph->t0e_1)
|
||||
if (d_internal_pvt_solver->galileo_ephemeris_map[galileo_eph->PRN].toe != galileo_eph->toe)
|
||||
{
|
||||
new_annotation = true;
|
||||
}
|
||||
@ -1211,14 +1241,14 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
{
|
||||
// New record!
|
||||
std::map<int32_t, Galileo_Ephemeris> new_gal_eph;
|
||||
new_gal_eph[galileo_eph->i_satellite_PRN] = *galileo_eph;
|
||||
new_gal_eph[galileo_eph->PRN] = *galileo_eph;
|
||||
d_rp->log_rinex_nav_gal_nav(d_type_of_rx, new_gal_eph);
|
||||
}
|
||||
}
|
||||
d_internal_pvt_solver->galileo_ephemeris_map[galileo_eph->i_satellite_PRN] = *galileo_eph;
|
||||
d_internal_pvt_solver->galileo_ephemeris_map[galileo_eph->PRN] = *galileo_eph;
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
d_user_pvt_solver->galileo_ephemeris_map[galileo_eph->i_satellite_PRN] = *galileo_eph;
|
||||
d_user_pvt_solver->galileo_ephemeris_map[galileo_eph->PRN] = *galileo_eph;
|
||||
}
|
||||
}
|
||||
else if (msg_type_hash_code == d_galileo_iono_sptr_type_hash_code)
|
||||
@ -1251,28 +1281,28 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
const Galileo_Almanac sv2 = galileo_almanac_helper->get_almanac(2);
|
||||
const Galileo_Almanac sv3 = galileo_almanac_helper->get_almanac(3);
|
||||
|
||||
if (sv1.i_satellite_PRN != 0)
|
||||
if (sv1.PRN != 0)
|
||||
{
|
||||
d_internal_pvt_solver->galileo_almanac_map[sv1.i_satellite_PRN] = sv1;
|
||||
d_internal_pvt_solver->galileo_almanac_map[sv1.PRN] = sv1;
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
d_user_pvt_solver->galileo_almanac_map[sv1.i_satellite_PRN] = sv1;
|
||||
d_user_pvt_solver->galileo_almanac_map[sv1.PRN] = sv1;
|
||||
}
|
||||
}
|
||||
if (sv2.i_satellite_PRN != 0)
|
||||
if (sv2.PRN != 0)
|
||||
{
|
||||
d_internal_pvt_solver->galileo_almanac_map[sv2.i_satellite_PRN] = sv2;
|
||||
d_internal_pvt_solver->galileo_almanac_map[sv2.PRN] = sv2;
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
d_user_pvt_solver->galileo_almanac_map[sv2.i_satellite_PRN] = sv2;
|
||||
d_user_pvt_solver->galileo_almanac_map[sv2.PRN] = sv2;
|
||||
}
|
||||
}
|
||||
if (sv3.i_satellite_PRN != 0)
|
||||
if (sv3.PRN != 0)
|
||||
{
|
||||
d_internal_pvt_solver->galileo_almanac_map[sv3.i_satellite_PRN] = sv3;
|
||||
d_internal_pvt_solver->galileo_almanac_map[sv3.PRN] = sv3;
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
d_user_pvt_solver->galileo_almanac_map[sv3.i_satellite_PRN] = sv3;
|
||||
d_user_pvt_solver->galileo_almanac_map[sv3.PRN] = sv3;
|
||||
}
|
||||
}
|
||||
DLOG(INFO) << "New Galileo Almanac data have arrived ";
|
||||
@ -1282,10 +1312,10 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
// ### Galileo Almanac ###
|
||||
const auto galileo_alm = boost::any_cast<std::shared_ptr<Galileo_Almanac>>(pmt::any_ref(msg));
|
||||
// update/insert new almanac record to the global almanac map
|
||||
d_internal_pvt_solver->galileo_almanac_map[galileo_alm->i_satellite_PRN] = *galileo_alm;
|
||||
d_internal_pvt_solver->galileo_almanac_map[galileo_alm->PRN] = *galileo_alm;
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
d_user_pvt_solver->galileo_almanac_map[galileo_alm->i_satellite_PRN] = *galileo_alm;
|
||||
d_user_pvt_solver->galileo_almanac_map[galileo_alm->PRN] = *galileo_alm;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1301,16 +1331,16 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
<< " and Ephemeris IOD in UTC = " << glonass_gnav_eph->compute_GLONASS_time(glonass_gnav_eph->d_t_b)
|
||||
<< " from SV = " << glonass_gnav_eph->i_satellite_slot_number;
|
||||
// update/insert new ephemeris record to the global ephemeris map
|
||||
if (d_rp->is_rinex_header_written()) // The header is already written, we can now log the navigation message data
|
||||
if (d_rinex_output_enabled && d_rp->is_rinex_header_written()) // The header is already written, we can now log the navigation message data
|
||||
{
|
||||
bool new_annotation = false;
|
||||
if (d_internal_pvt_solver->glonass_gnav_ephemeris_map.find(glonass_gnav_eph->i_satellite_PRN) == d_internal_pvt_solver->glonass_gnav_ephemeris_map.cend())
|
||||
if (d_internal_pvt_solver->glonass_gnav_ephemeris_map.find(glonass_gnav_eph->PRN) == d_internal_pvt_solver->glonass_gnav_ephemeris_map.cend())
|
||||
{
|
||||
new_annotation = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d_internal_pvt_solver->glonass_gnav_ephemeris_map[glonass_gnav_eph->i_satellite_PRN].d_t_b != glonass_gnav_eph->d_t_b)
|
||||
if (d_internal_pvt_solver->glonass_gnav_ephemeris_map[glonass_gnav_eph->PRN].d_t_b != glonass_gnav_eph->d_t_b)
|
||||
{
|
||||
new_annotation = true;
|
||||
}
|
||||
@ -1319,14 +1349,14 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
{
|
||||
// New record!
|
||||
std::map<int32_t, Glonass_Gnav_Ephemeris> new_glo_eph;
|
||||
new_glo_eph[glonass_gnav_eph->i_satellite_PRN] = *glonass_gnav_eph;
|
||||
new_glo_eph[glonass_gnav_eph->PRN] = *glonass_gnav_eph;
|
||||
d_rp->log_rinex_nav_glo_gnav(d_type_of_rx, new_glo_eph);
|
||||
}
|
||||
}
|
||||
d_internal_pvt_solver->glonass_gnav_ephemeris_map[glonass_gnav_eph->i_satellite_PRN] = *glonass_gnav_eph;
|
||||
d_internal_pvt_solver->glonass_gnav_ephemeris_map[glonass_gnav_eph->PRN] = *glonass_gnav_eph;
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
d_user_pvt_solver->glonass_gnav_ephemeris_map[glonass_gnav_eph->i_satellite_PRN] = *glonass_gnav_eph;
|
||||
d_user_pvt_solver->glonass_gnav_ephemeris_map[glonass_gnav_eph->PRN] = *glonass_gnav_eph;
|
||||
}
|
||||
}
|
||||
else if (msg_type_hash_code == d_glonass_gnav_utc_model_sptr_type_hash_code)
|
||||
@ -1359,21 +1389,21 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
// ### Beidou EPHEMERIS ###
|
||||
const auto bds_dnav_eph = boost::any_cast<std::shared_ptr<Beidou_Dnav_Ephemeris>>(pmt::any_ref(msg));
|
||||
DLOG(INFO) << "Ephemeris record has arrived from SAT ID "
|
||||
<< bds_dnav_eph->i_satellite_PRN << " (Block "
|
||||
<< bds_dnav_eph->satelliteBlock[bds_dnav_eph->i_satellite_PRN] << ")"
|
||||
<< "inserted with Toe=" << bds_dnav_eph->d_Toe << " and BDS Week="
|
||||
<< bds_dnav_eph->i_BEIDOU_week;
|
||||
<< bds_dnav_eph->PRN << " (Block "
|
||||
<< bds_dnav_eph->satelliteBlock[bds_dnav_eph->PRN] << ")"
|
||||
<< "inserted with Toe=" << bds_dnav_eph->toe << " and BDS Week="
|
||||
<< bds_dnav_eph->WN;
|
||||
// update/insert new ephemeris record to the global ephemeris map
|
||||
if (d_rp->is_rinex_header_written()) // The header is already written, we can now log the navigation message data
|
||||
if (d_rinex_output_enabled && d_rp->is_rinex_header_written()) // The header is already written, we can now log the navigation message data
|
||||
{
|
||||
bool new_annotation = false;
|
||||
if (d_internal_pvt_solver->beidou_dnav_ephemeris_map.find(bds_dnav_eph->i_satellite_PRN) == d_internal_pvt_solver->beidou_dnav_ephemeris_map.cend())
|
||||
if (d_internal_pvt_solver->beidou_dnav_ephemeris_map.find(bds_dnav_eph->PRN) == d_internal_pvt_solver->beidou_dnav_ephemeris_map.cend())
|
||||
{
|
||||
new_annotation = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d_internal_pvt_solver->beidou_dnav_ephemeris_map[bds_dnav_eph->i_satellite_PRN].d_Toc != bds_dnav_eph->d_Toc)
|
||||
if (d_internal_pvt_solver->beidou_dnav_ephemeris_map[bds_dnav_eph->PRN].toc != bds_dnav_eph->toc)
|
||||
{
|
||||
new_annotation = true;
|
||||
}
|
||||
@ -1382,14 +1412,14 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
{
|
||||
// New record!
|
||||
std::map<int32_t, Beidou_Dnav_Ephemeris> new_bds_eph;
|
||||
new_bds_eph[bds_dnav_eph->i_satellite_PRN] = *bds_dnav_eph;
|
||||
new_bds_eph[bds_dnav_eph->PRN] = *bds_dnav_eph;
|
||||
d_rp->log_rinex_nav_bds_dnav(d_type_of_rx, new_bds_eph);
|
||||
}
|
||||
}
|
||||
d_internal_pvt_solver->beidou_dnav_ephemeris_map[bds_dnav_eph->i_satellite_PRN] = *bds_dnav_eph;
|
||||
d_internal_pvt_solver->beidou_dnav_ephemeris_map[bds_dnav_eph->PRN] = *bds_dnav_eph;
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
d_user_pvt_solver->beidou_dnav_ephemeris_map[bds_dnav_eph->i_satellite_PRN] = *bds_dnav_eph;
|
||||
d_user_pvt_solver->beidou_dnav_ephemeris_map[bds_dnav_eph->PRN] = *bds_dnav_eph;
|
||||
}
|
||||
}
|
||||
else if (msg_type_hash_code == d_beidou_dnav_iono_sptr_type_hash_code)
|
||||
@ -1418,10 +1448,10 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
{
|
||||
// ### BeiDou ALMANAC ###
|
||||
const auto bds_dnav_almanac = boost::any_cast<std::shared_ptr<Beidou_Dnav_Almanac>>(pmt::any_ref(msg));
|
||||
d_internal_pvt_solver->beidou_dnav_almanac_map[bds_dnav_almanac->i_satellite_PRN] = *bds_dnav_almanac;
|
||||
d_internal_pvt_solver->beidou_dnav_almanac_map[bds_dnav_almanac->PRN] = *bds_dnav_almanac;
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
d_user_pvt_solver->beidou_dnav_almanac_map[bds_dnav_almanac->i_satellite_PRN] = *bds_dnav_almanac;
|
||||
d_user_pvt_solver->beidou_dnav_almanac_map[bds_dnav_almanac->PRN] = *bds_dnav_almanac;
|
||||
}
|
||||
DLOG(INFO) << "New BeiDou DNAV almanac record has arrived ";
|
||||
}
|
||||
@ -1807,7 +1837,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
|
||||
if (tmp_eph_iter_gps != d_internal_pvt_solver->gps_ephemeris_map.cend())
|
||||
{
|
||||
const uint32_t prn_aux = tmp_eph_iter_gps->second.i_satellite_PRN;
|
||||
const uint32_t prn_aux = tmp_eph_iter_gps->second.PRN;
|
||||
if ((prn_aux == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal) == "1C"))
|
||||
{
|
||||
store_valid_observable = true;
|
||||
@ -1815,7 +1845,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
}
|
||||
if (tmp_eph_iter_gal != d_internal_pvt_solver->galileo_ephemeris_map.cend())
|
||||
{
|
||||
const uint32_t prn_aux = tmp_eph_iter_gal->second.i_satellite_PRN;
|
||||
const uint32_t prn_aux = tmp_eph_iter_gal->second.PRN;
|
||||
if ((prn_aux == in[i][epoch].PRN) and ((std::string(in[i][epoch].Signal) == "1B") or (std::string(in[i][epoch].Signal) == "5X") or (std::string(in[i][epoch].Signal) == "7X")))
|
||||
{
|
||||
store_valid_observable = true;
|
||||
@ -1823,7 +1853,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
}
|
||||
if (tmp_eph_iter_cnav != d_internal_pvt_solver->gps_cnav_ephemeris_map.cend())
|
||||
{
|
||||
const uint32_t prn_aux = tmp_eph_iter_cnav->second.i_satellite_PRN;
|
||||
const uint32_t prn_aux = tmp_eph_iter_cnav->second.PRN;
|
||||
if ((prn_aux == in[i][epoch].PRN) and ((std::string(in[i][epoch].Signal) == "2S") or (std::string(in[i][epoch].Signal) == "L5")))
|
||||
{
|
||||
store_valid_observable = true;
|
||||
@ -1831,7 +1861,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
}
|
||||
if (tmp_eph_iter_glo_gnav != d_internal_pvt_solver->glonass_gnav_ephemeris_map.cend())
|
||||
{
|
||||
const uint32_t prn_aux = tmp_eph_iter_glo_gnav->second.i_satellite_PRN;
|
||||
const uint32_t prn_aux = tmp_eph_iter_glo_gnav->second.PRN;
|
||||
if ((prn_aux == in[i][epoch].PRN) and ((std::string(in[i][epoch].Signal) == "1G") or (std::string(in[i][epoch].Signal) == "2G")))
|
||||
{
|
||||
store_valid_observable = true;
|
||||
@ -1839,7 +1869,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
}
|
||||
if (tmp_eph_iter_bds_dnav != d_internal_pvt_solver->beidou_dnav_ephemeris_map.cend())
|
||||
{
|
||||
const uint32_t prn_aux = tmp_eph_iter_bds_dnav->second.i_satellite_PRN;
|
||||
const uint32_t prn_aux = tmp_eph_iter_bds_dnav->second.PRN;
|
||||
if ((prn_aux == in[i][epoch].PRN) and ((std::string(in[i][epoch].Signal) == "B1") or (std::string(in[i][epoch].Signal) == "B3")))
|
||||
{
|
||||
store_valid_observable = true;
|
||||
|
@ -52,6 +52,7 @@ class Gps_Ephemeris;
|
||||
class Gpx_Printer;
|
||||
class Kml_Printer;
|
||||
class Monitor_Pvt_Udp_Sink;
|
||||
class Monitor_Ephemeris_Udp_Sink;
|
||||
class Nmea_Printer;
|
||||
class Pvt_Conf;
|
||||
class Rinex_Printer;
|
||||
@ -168,6 +169,7 @@ private:
|
||||
std::unique_ptr<GeoJSON_Printer> d_geojson_printer;
|
||||
std::unique_ptr<Rtcm_Printer> d_rtcm_printer;
|
||||
std::unique_ptr<Monitor_Pvt_Udp_Sink> d_udp_sink_ptr;
|
||||
std::unique_ptr<Monitor_Ephemeris_Udp_Sink> d_eph_udp_sink_ptr;
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> d_start;
|
||||
std::chrono::time_point<std::chrono::system_clock> d_end;
|
||||
@ -260,6 +262,7 @@ private:
|
||||
bool d_first_fix;
|
||||
bool d_xml_storage;
|
||||
bool d_flag_monitor_pvt_enabled;
|
||||
bool d_flag_monitor_ephemeris_enabled;
|
||||
bool d_show_local_time_zone;
|
||||
bool d_waiting_obs_block_rx_clock_offset_correction_msg;
|
||||
bool d_enable_rx_clock_correction;
|
||||
|
@ -5,6 +5,8 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${CMAKE_SOURCE_DIR}/docs/protobuf/monitor_pvt.proto)
|
||||
protobuf_generate_cpp(PROTO_SRCS2 PROTO_HDRS2 ${CMAKE_SOURCE_DIR}/docs/protobuf/gps_ephemeris.proto)
|
||||
protobuf_generate_cpp(PROTO_SRCS3 PROTO_HDRS3 ${CMAKE_SOURCE_DIR}/docs/protobuf/galileo_ephemeris.proto)
|
||||
|
||||
set(PVT_LIB_SOURCES
|
||||
pvt_conf.cc
|
||||
@ -18,6 +20,7 @@ set(PVT_LIB_SOURCES
|
||||
rtcm.cc
|
||||
rtklib_solver.cc
|
||||
monitor_pvt_udp_sink.cc
|
||||
monitor_ephemeris_udp_sink.cc
|
||||
)
|
||||
|
||||
set(PVT_LIB_HEADERS
|
||||
@ -34,6 +37,9 @@ set(PVT_LIB_HEADERS
|
||||
monitor_pvt_udp_sink.h
|
||||
monitor_pvt.h
|
||||
serdes_monitor_pvt.h
|
||||
serdes_galileo_eph.h
|
||||
serdes_gps_eph.h
|
||||
monitor_ephemeris_udp_sink.h
|
||||
)
|
||||
|
||||
list(SORT PVT_LIB_HEADERS)
|
||||
@ -44,14 +50,27 @@ if(USE_CMAKE_TARGET_SOURCES)
|
||||
target_sources(pvt_libs
|
||||
PRIVATE
|
||||
${PROTO_SRCS}
|
||||
${PROTO_SRCS2}
|
||||
${PROTO_SRCS3}
|
||||
${PROTO_HDRS}
|
||||
${PROTO_HDRS2}
|
||||
${PROTO_HDRS3}
|
||||
${PVT_LIB_SOURCES}
|
||||
PUBLIC
|
||||
${PVT_LIB_HEADERS}
|
||||
)
|
||||
else()
|
||||
source_group(Headers FILES ${PVT_LIB_HEADERS} ${PROTO_HDRS})
|
||||
add_library(pvt_libs ${PVT_LIB_SOURCES} ${PROTO_SRCS} ${PVT_LIB_HEADERS} ${PROTO_HDRS})
|
||||
source_group(Headers FILES ${PVT_LIB_HEADERS} ${PROTO_HDRS} ${PROTO_HDRS2} ${PROTO_HDRS3})
|
||||
add_library(pvt_libs
|
||||
${PVT_LIB_SOURCES}
|
||||
${PROTO_SRCS}
|
||||
${PROTO_SRCS2}
|
||||
${PROTO_SRCS3}
|
||||
${PVT_LIB_HEADERS}
|
||||
${PROTO_HDRS}
|
||||
${PROTO_HDRS2}
|
||||
${PROTO_HDRS3}
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(pvt_libs
|
||||
|
112
src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc
Normal file
112
src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc
Normal file
@ -0,0 +1,112 @@
|
||||
/*!
|
||||
* \file monitor_ephemeris_udp_sink.cc
|
||||
* \brief Interface of a class that sends serialized Gps_Ephemeris and
|
||||
* Galileo_Ephemeris objects over udp to one or multiple endpoints.
|
||||
* \author Javier Arribas, 2021. jarribas(at)cttc.es
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "monitor_ephemeris_udp_sink.h"
|
||||
#include <boost/archive/binary_oarchive.hpp>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
Monitor_Ephemeris_Udp_Sink::Monitor_Ephemeris_Udp_Sink(const std::vector<std::string>& addresses, const uint16_t& port, bool protobuf_enabled) : socket{io_context}
|
||||
{
|
||||
for (const auto& address : addresses)
|
||||
{
|
||||
boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), port);
|
||||
endpoints.push_back(endpoint);
|
||||
}
|
||||
|
||||
use_protobuf = protobuf_enabled;
|
||||
if (use_protobuf)
|
||||
{
|
||||
serdes_gal = Serdes_Galileo_Eph();
|
||||
serdes_gps = Serdes_Gps_Eph();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Monitor_Ephemeris_Udp_Sink::write_galileo_ephemeris(const std::shared_ptr<Galileo_Ephemeris>& monitor_gal_eph)
|
||||
{
|
||||
std::string outbound_data;
|
||||
if (use_protobuf == false)
|
||||
{
|
||||
std::ostringstream archive_stream;
|
||||
boost::archive::binary_oarchive oa{archive_stream};
|
||||
oa << *monitor_gal_eph;
|
||||
outbound_data = archive_stream.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
outbound_data = "E";
|
||||
outbound_data.append(serdes_gal.createProtobuffer(monitor_gal_eph));
|
||||
}
|
||||
|
||||
for (const auto& endpoint : endpoints)
|
||||
{
|
||||
socket.open(endpoint.protocol(), error);
|
||||
socket.connect(endpoint, error);
|
||||
|
||||
try
|
||||
{
|
||||
if (socket.send(boost::asio::buffer(outbound_data)) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (boost::system::system_error const& e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Monitor_Ephemeris_Udp_Sink::write_gps_ephemeris(const std::shared_ptr<Gps_Ephemeris>& monitor_gps_eph)
|
||||
{
|
||||
std::string outbound_data;
|
||||
if (use_protobuf == false)
|
||||
{
|
||||
std::ostringstream archive_stream;
|
||||
boost::archive::binary_oarchive oa{archive_stream};
|
||||
oa << *monitor_gps_eph;
|
||||
outbound_data = archive_stream.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
outbound_data = "G";
|
||||
outbound_data.append(serdes_gps.createProtobuffer(monitor_gps_eph));
|
||||
}
|
||||
|
||||
for (const auto& endpoint : endpoints)
|
||||
{
|
||||
socket.open(endpoint.protocol(), error);
|
||||
socket.connect(endpoint, error);
|
||||
|
||||
try
|
||||
{
|
||||
if (socket.send(boost::asio::buffer(outbound_data)) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (boost::system::system_error const& e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
62
src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.h
Normal file
62
src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*!
|
||||
* \file monitor_ephemeris_udp_sink.h
|
||||
* \brief Interface of a class that sends serialized Gps_Ephemeris and
|
||||
* Galileo_Ephemeris objects over udp to one or multiple endpoints.
|
||||
* \author Javier Arribas, 2021. jarribas(at)cttc.es
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_MONITOR_EPHEMERIS_UDP_SINK_H
|
||||
#define GNSS_SDR_MONITOR_EPHEMERIS_UDP_SINK_H
|
||||
|
||||
#include "galileo_ephemeris.h"
|
||||
#include "gps_ephemeris.h"
|
||||
#include "serdes_galileo_eph.h"
|
||||
#include "serdes_gps_eph.h"
|
||||
#include <boost/asio.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/** \addtogroup PVT
|
||||
* \{ */
|
||||
/** \addtogroup PVT_libs
|
||||
* \{ */
|
||||
|
||||
|
||||
#if USE_BOOST_ASIO_IO_CONTEXT
|
||||
using b_io_context = boost::asio::io_context;
|
||||
#else
|
||||
using b_io_context = boost::asio::io_service;
|
||||
#endif
|
||||
|
||||
class Monitor_Ephemeris_Udp_Sink
|
||||
{
|
||||
public:
|
||||
Monitor_Ephemeris_Udp_Sink(const std::vector<std::string>& addresses, const uint16_t& port, bool protobuf_enabled);
|
||||
bool write_gps_ephemeris(const std::shared_ptr<Gps_Ephemeris>& monitor_gps_eph);
|
||||
bool write_galileo_ephemeris(const std::shared_ptr<Galileo_Ephemeris>& monitor_gal_eph);
|
||||
|
||||
private:
|
||||
Serdes_Galileo_Eph serdes_gal;
|
||||
Serdes_Gps_Eph serdes_gps;
|
||||
b_io_context io_context;
|
||||
boost::asio::ip::udp::socket socket;
|
||||
std::vector<boost::asio::ip::udp::endpoint> endpoints;
|
||||
boost::system::error_code error;
|
||||
bool use_protobuf;
|
||||
};
|
||||
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GNSS_SDR_MONITOR_EPHEMERIS_UDP_SINK_H
|
@ -29,7 +29,7 @@ Pvt_Conf::Pvt_Conf()
|
||||
max_obs_block_rx_clock_offset_ms = 40;
|
||||
rinex_version = 0;
|
||||
rinexobs_rate_ms = 0;
|
||||
rinex_name = "-";
|
||||
rinex_name = std::string("-");
|
||||
|
||||
dump = false;
|
||||
dump_mat = true;
|
||||
@ -61,8 +61,10 @@ Pvt_Conf::Pvt_Conf()
|
||||
|
||||
enable_rx_clock_correction = true;
|
||||
monitor_enabled = false;
|
||||
monitor_ephemeris_enabled = false;
|
||||
protobuf_enabled = true;
|
||||
udp_port = 0;
|
||||
udp_eph_port = 0;
|
||||
pre_2009_file = false;
|
||||
show_local_time_zone = false;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
std::string xml_output_path;
|
||||
std::string rtcm_output_file_path;
|
||||
std::string udp_addresses;
|
||||
std::string udp_eph_addresses;
|
||||
|
||||
uint32_t type_of_receiver;
|
||||
int32_t output_rate_ms;
|
||||
@ -60,6 +61,7 @@ public:
|
||||
int32_t rinexobs_rate_ms;
|
||||
int32_t max_obs_block_rx_clock_offset_ms;
|
||||
int udp_port;
|
||||
int udp_eph_port;
|
||||
|
||||
uint16_t rtcm_tcp_port;
|
||||
uint16_t rtcm_station_id;
|
||||
@ -76,6 +78,7 @@ public:
|
||||
bool xml_output_enabled;
|
||||
bool rtcm_output_file_enabled;
|
||||
bool monitor_enabled;
|
||||
bool monitor_ephemeris_enabled;
|
||||
bool protobuf_enabled;
|
||||
bool enable_rx_clock_correction;
|
||||
bool show_local_time_zone;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1625,95 +1625,95 @@ int32_t Rtcm::read_MT1019(const std::string& message, Gps_Ephemeris& gps_eph) co
|
||||
}
|
||||
|
||||
// Fill Gps Ephemeris with message data content
|
||||
gps_eph.i_satellite_PRN = static_cast<uint32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 6)));
|
||||
gps_eph.PRN = static_cast<uint32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 6)));
|
||||
index += 6;
|
||||
|
||||
gps_eph.i_GPS_week = static_cast<int32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 10)));
|
||||
gps_eph.WN = static_cast<int32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 10)));
|
||||
index += 10;
|
||||
|
||||
gps_eph.i_SV_accuracy = static_cast<int32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 4)));
|
||||
gps_eph.SV_accuracy = static_cast<int32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 4)));
|
||||
index += 4;
|
||||
|
||||
gps_eph.i_code_on_L2 = static_cast<int32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 2)));
|
||||
gps_eph.code_on_L2 = static_cast<int32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 2)));
|
||||
index += 2;
|
||||
|
||||
gps_eph.d_IDOT = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 14))) * I_DOT_LSB;
|
||||
gps_eph.idot = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 14))) * I_DOT_LSB;
|
||||
index += 14;
|
||||
|
||||
gps_eph.d_IODE_SF2 = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 8)));
|
||||
gps_eph.d_IODE_SF3 = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 8)));
|
||||
gps_eph.IODE_SF2 = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 8)));
|
||||
gps_eph.IODE_SF3 = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 8)));
|
||||
index += 8;
|
||||
|
||||
gps_eph.d_Toc = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 16))) * T_OC_LSB;
|
||||
gps_eph.toc = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 16))) * T_OC_LSB;
|
||||
index += 16;
|
||||
|
||||
gps_eph.d_A_f2 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 8))) * A_F2_LSB;
|
||||
gps_eph.af2 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 8))) * A_F2_LSB;
|
||||
index += 8;
|
||||
|
||||
gps_eph.d_A_f1 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * A_F1_LSB;
|
||||
gps_eph.af1 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * A_F1_LSB;
|
||||
index += 16;
|
||||
|
||||
gps_eph.d_A_f0 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 22))) * A_F0_LSB;
|
||||
gps_eph.af0 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 22))) * A_F0_LSB;
|
||||
index += 22;
|
||||
|
||||
gps_eph.d_IODC = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 10)));
|
||||
gps_eph.IODC = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 10)));
|
||||
index += 10;
|
||||
|
||||
gps_eph.d_Crs = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_RS_LSB;
|
||||
gps_eph.Crs = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_RS_LSB;
|
||||
index += 16;
|
||||
|
||||
gps_eph.d_Delta_n = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * DELTA_N_LSB;
|
||||
gps_eph.delta_n = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * DELTA_N_LSB;
|
||||
index += 16;
|
||||
|
||||
gps_eph.d_M_0 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * M_0_LSB;
|
||||
gps_eph.M_0 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * M_0_LSB;
|
||||
index += 32;
|
||||
|
||||
gps_eph.d_Cuc = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_UC_LSB;
|
||||
gps_eph.Cuc = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_UC_LSB;
|
||||
index += 16;
|
||||
|
||||
gps_eph.d_e_eccentricity = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 32))) * ECCENTRICITY_LSB;
|
||||
gps_eph.ecc = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 32))) * ECCENTRICITY_LSB;
|
||||
index += 32;
|
||||
|
||||
gps_eph.d_Cus = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_US_LSB;
|
||||
gps_eph.Cus = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_US_LSB;
|
||||
index += 16;
|
||||
|
||||
gps_eph.d_sqrt_A = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 32))) * SQRT_A_LSB;
|
||||
gps_eph.sqrtA = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 32))) * SQRT_A_LSB;
|
||||
index += 32;
|
||||
|
||||
gps_eph.d_Toe = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 16))) * T_OE_LSB;
|
||||
gps_eph.toe = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 16))) * T_OE_LSB;
|
||||
index += 16;
|
||||
|
||||
gps_eph.d_Cic = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_IC_LSB;
|
||||
gps_eph.Cic = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_IC_LSB;
|
||||
index += 16;
|
||||
|
||||
gps_eph.d_OMEGA0 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * OMEGA_0_LSB;
|
||||
gps_eph.OMEGA_0 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * OMEGA_0_LSB;
|
||||
index += 32;
|
||||
|
||||
gps_eph.d_Cis = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_IS_LSB;
|
||||
gps_eph.Cis = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_IS_LSB;
|
||||
index += 16;
|
||||
|
||||
gps_eph.d_i_0 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * I_0_LSB;
|
||||
gps_eph.i_0 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * I_0_LSB;
|
||||
index += 32;
|
||||
|
||||
gps_eph.d_Crc = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_RC_LSB;
|
||||
gps_eph.Crc = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_RC_LSB;
|
||||
index += 16;
|
||||
|
||||
gps_eph.d_OMEGA = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * OMEGA_LSB;
|
||||
gps_eph.omega = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * OMEGA_LSB;
|
||||
index += 32;
|
||||
|
||||
gps_eph.d_OMEGA_DOT = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 24))) * OMEGA_DOT_LSB;
|
||||
gps_eph.OMEGAdot = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 24))) * OMEGA_DOT_LSB;
|
||||
index += 24;
|
||||
|
||||
gps_eph.d_TGD = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 8))) * T_GD_LSB;
|
||||
gps_eph.TGD = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 8))) * T_GD_LSB;
|
||||
index += 8;
|
||||
|
||||
gps_eph.i_SV_health = static_cast<int32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 6)));
|
||||
gps_eph.SV_health = static_cast<int32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 6)));
|
||||
index += 6;
|
||||
|
||||
gps_eph.b_L2_P_data_flag = static_cast<bool>(Rtcm::bin_to_uint(message_bin.substr(index, 1)));
|
||||
gps_eph.L2_P_data_flag = static_cast<bool>(Rtcm::bin_to_uint(message_bin.substr(index, 1)));
|
||||
index += 1;
|
||||
|
||||
gps_eph.b_fit_interval_flag = static_cast<bool>(Rtcm::bin_to_uint(message_bin.substr(index, 1)));
|
||||
gps_eph.fit_interval_flag = static_cast<bool>(Rtcm::bin_to_uint(message_bin.substr(index, 1)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2162,79 +2162,79 @@ int32_t Rtcm::read_MT1045(const std::string& message, Galileo_Ephemeris& gal_eph
|
||||
}
|
||||
|
||||
// Fill Galileo Ephemeris with message data content
|
||||
gal_eph.i_satellite_PRN = static_cast<uint32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 6)));
|
||||
gal_eph.PRN = static_cast<uint32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 6)));
|
||||
index += 6;
|
||||
|
||||
gal_eph.WN_5 = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 12)));
|
||||
gal_eph.WN = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 12)));
|
||||
index += 12;
|
||||
|
||||
gal_eph.IOD_nav_1 = static_cast<int32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 10)));
|
||||
gal_eph.IOD_nav = static_cast<int32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 10)));
|
||||
index += 10;
|
||||
|
||||
gal_eph.SISA_3 = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 8)));
|
||||
gal_eph.SISA = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 8)));
|
||||
index += 8;
|
||||
|
||||
gal_eph.iDot_2 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 14))) * I_DOT_2_LSB;
|
||||
gal_eph.idot = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 14))) * I_DOT_2_LSB;
|
||||
index += 14;
|
||||
|
||||
gal_eph.t0c_4 = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 14))) * T0C_4_LSB;
|
||||
gal_eph.toc = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 14))) * T0C_4_LSB;
|
||||
index += 14;
|
||||
|
||||
gal_eph.af2_4 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 6))) * AF2_4_LSB;
|
||||
gal_eph.af2 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 6))) * AF2_4_LSB;
|
||||
index += 6;
|
||||
|
||||
gal_eph.af1_4 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 21))) * AF1_4_LSB;
|
||||
gal_eph.af1 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 21))) * AF1_4_LSB;
|
||||
index += 21;
|
||||
|
||||
gal_eph.af0_4 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 31))) * AF0_4_LSB;
|
||||
gal_eph.af0 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 31))) * AF0_4_LSB;
|
||||
index += 31;
|
||||
|
||||
gal_eph.C_rs_3 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_RS_3_LSB;
|
||||
gal_eph.Crs = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_RS_3_LSB;
|
||||
index += 16;
|
||||
|
||||
gal_eph.delta_n_3 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * DELTA_N_3_LSB;
|
||||
gal_eph.delta_n = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * DELTA_N_3_LSB;
|
||||
index += 16;
|
||||
|
||||
gal_eph.M0_1 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * M0_1_LSB;
|
||||
gal_eph.M_0 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * M0_1_LSB;
|
||||
index += 32;
|
||||
|
||||
gal_eph.C_uc_3 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_UC_3_LSB;
|
||||
gal_eph.Cuc = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_UC_3_LSB;
|
||||
index += 16;
|
||||
|
||||
gal_eph.e_1 = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 32))) * E_1_LSB;
|
||||
gal_eph.ecc = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 32))) * E_1_LSB;
|
||||
index += 32;
|
||||
|
||||
gal_eph.C_us_3 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_US_3_LSB;
|
||||
gal_eph.Cus = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_US_3_LSB;
|
||||
index += 16;
|
||||
|
||||
gal_eph.A_1 = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 32))) * A_1_LSB_GAL;
|
||||
gal_eph.sqrtA = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 32))) * A_1_LSB_GAL;
|
||||
index += 32;
|
||||
|
||||
gal_eph.t0e_1 = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 14))) * T0E_1_LSB;
|
||||
gal_eph.toe = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 14))) * T0E_1_LSB;
|
||||
index += 14;
|
||||
|
||||
gal_eph.C_ic_4 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_IC_4_LSB;
|
||||
gal_eph.Cic = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_IC_4_LSB;
|
||||
index += 16;
|
||||
|
||||
gal_eph.OMEGA_0_2 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * OMEGA_0_2_LSB;
|
||||
gal_eph.OMEGA_0 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * OMEGA_0_2_LSB;
|
||||
index += 32;
|
||||
|
||||
gal_eph.C_is_4 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_IS_4_LSB;
|
||||
gal_eph.Cis = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_IS_4_LSB;
|
||||
index += 16;
|
||||
|
||||
gal_eph.i_0_2 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * I_0_2_LSB;
|
||||
gal_eph.i_0 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * I_0_2_LSB;
|
||||
index += 32;
|
||||
|
||||
gal_eph.C_rc_3 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_RC_3_LSB;
|
||||
gal_eph.Crc = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 16))) * C_RC_3_LSB;
|
||||
index += 16;
|
||||
|
||||
gal_eph.omega_2 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * OMEGA_2_LSB;
|
||||
gal_eph.omega = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 32))) * OMEGA_2_LSB;
|
||||
index += 32;
|
||||
|
||||
gal_eph.OMEGA_dot_3 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 24))) * OMEGA_DOT_3_LSB;
|
||||
gal_eph.OMEGAdot = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 24))) * OMEGA_DOT_3_LSB;
|
||||
index += 24;
|
||||
|
||||
gal_eph.BGD_E1E5a_5 = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 10)));
|
||||
gal_eph.BGD_E1E5a = static_cast<double>(Rtcm::bin_to_int(message_bin.substr(index, 10)));
|
||||
index += 10;
|
||||
|
||||
gal_eph.E5a_HS = static_cast<uint32_t>(Rtcm::bin_to_uint(message_bin.substr(index, 2)));
|
||||
@ -2266,23 +2266,23 @@ std::string Rtcm::print_MSM_1(const Gps_Ephemeris& gps_eph,
|
||||
bool more_messages)
|
||||
{
|
||||
uint32_t msg_number = 0;
|
||||
if (gps_eph.i_satellite_PRN != 0)
|
||||
if (gps_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1071;
|
||||
}
|
||||
if (gps_cnav_eph.i_satellite_PRN != 0)
|
||||
if (gps_cnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1071;
|
||||
}
|
||||
if (glo_gnav_eph.i_satellite_PRN != 0)
|
||||
if (glo_gnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1081;
|
||||
}
|
||||
if (gal_eph.i_satellite_PRN != 0)
|
||||
if (gal_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1091;
|
||||
}
|
||||
if (((gps_eph.i_satellite_PRN != 0) || (gps_cnav_eph.i_satellite_PRN != 0)) && (gal_eph.i_satellite_PRN != 0) && (glo_gnav_eph.i_satellite_PRN != 0))
|
||||
if (((gps_eph.PRN != 0) || (gps_cnav_eph.PRN != 0)) && (gal_eph.PRN != 0) && (glo_gnav_eph.PRN != 0))
|
||||
{
|
||||
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; // print two messages?
|
||||
}
|
||||
@ -2463,23 +2463,23 @@ std::string Rtcm::print_MSM_2(const Gps_Ephemeris& gps_eph,
|
||||
bool more_messages)
|
||||
{
|
||||
uint32_t msg_number = 0;
|
||||
if (gps_eph.i_satellite_PRN != 0)
|
||||
if (gps_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1072;
|
||||
}
|
||||
if (gps_cnav_eph.i_satellite_PRN != 0)
|
||||
if (gps_cnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1072;
|
||||
}
|
||||
if (glo_gnav_eph.i_satellite_PRN != 0)
|
||||
if (glo_gnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1082;
|
||||
}
|
||||
if (gal_eph.i_satellite_PRN != 0)
|
||||
if (gal_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1092;
|
||||
}
|
||||
if (((gps_eph.i_satellite_PRN != 0) || (gps_cnav_eph.i_satellite_PRN != 0)) && (gal_eph.i_satellite_PRN != 0) && (glo_gnav_eph.i_satellite_PRN != 0))
|
||||
if (((gps_eph.PRN != 0) || (gps_cnav_eph.PRN != 0)) && (gal_eph.PRN != 0) && (glo_gnav_eph.PRN != 0))
|
||||
{
|
||||
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; // print two messages?
|
||||
}
|
||||
@ -2577,23 +2577,23 @@ std::string Rtcm::print_MSM_3(const Gps_Ephemeris& gps_eph,
|
||||
bool more_messages)
|
||||
{
|
||||
uint32_t msg_number = 0;
|
||||
if (gps_eph.i_satellite_PRN != 0)
|
||||
if (gps_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1073;
|
||||
}
|
||||
if (gps_cnav_eph.i_satellite_PRN != 0)
|
||||
if (gps_cnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1073;
|
||||
}
|
||||
if (glo_gnav_eph.i_satellite_PRN != 0)
|
||||
if (glo_gnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1083;
|
||||
}
|
||||
if (gal_eph.i_satellite_PRN != 0)
|
||||
if (gal_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1093;
|
||||
}
|
||||
if (((gps_eph.i_satellite_PRN != 0) || (gps_cnav_eph.i_satellite_PRN != 0)) && (gal_eph.i_satellite_PRN != 0) && (glo_gnav_eph.i_satellite_PRN != 0))
|
||||
if (((gps_eph.PRN != 0) || (gps_cnav_eph.PRN != 0)) && (gal_eph.PRN != 0) && (glo_gnav_eph.PRN != 0))
|
||||
{
|
||||
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; // print two messages?
|
||||
}
|
||||
@ -2694,23 +2694,23 @@ std::string Rtcm::print_MSM_4(const Gps_Ephemeris& gps_eph,
|
||||
bool more_messages)
|
||||
{
|
||||
uint32_t msg_number = 0;
|
||||
if (gps_eph.i_satellite_PRN != 0)
|
||||
if (gps_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1074;
|
||||
}
|
||||
if (gps_cnav_eph.i_satellite_PRN != 0)
|
||||
if (gps_cnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1074;
|
||||
}
|
||||
if (glo_gnav_eph.i_satellite_PRN != 0)
|
||||
if (glo_gnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1084;
|
||||
}
|
||||
if (gal_eph.i_satellite_PRN != 0)
|
||||
if (gal_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1094;
|
||||
}
|
||||
if (((gps_eph.i_satellite_PRN != 0) || (gps_cnav_eph.i_satellite_PRN != 0)) && (gal_eph.i_satellite_PRN != 0) && (glo_gnav_eph.i_satellite_PRN != 0))
|
||||
if (((gps_eph.PRN != 0) || (gps_cnav_eph.PRN != 0)) && (gal_eph.PRN != 0) && (glo_gnav_eph.PRN != 0))
|
||||
{
|
||||
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; // print two messages?
|
||||
}
|
||||
@ -2857,23 +2857,23 @@ std::string Rtcm::print_MSM_5(const Gps_Ephemeris& gps_eph,
|
||||
bool more_messages)
|
||||
{
|
||||
uint32_t msg_number = 0;
|
||||
if (gps_eph.i_satellite_PRN != 0)
|
||||
if (gps_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1075;
|
||||
}
|
||||
if (gps_cnav_eph.i_satellite_PRN != 0)
|
||||
if (gps_cnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1075;
|
||||
}
|
||||
if (glo_gnav_eph.i_satellite_PRN != 0)
|
||||
if (glo_gnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1085;
|
||||
}
|
||||
if (gal_eph.i_satellite_PRN != 0)
|
||||
if (gal_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1095;
|
||||
}
|
||||
if (((gps_eph.i_satellite_PRN != 0) || (gps_cnav_eph.i_satellite_PRN != 0)) && (gal_eph.i_satellite_PRN != 0) && (glo_gnav_eph.i_satellite_PRN != 0))
|
||||
if (((gps_eph.PRN != 0) || (gps_cnav_eph.PRN != 0)) && (gal_eph.PRN != 0) && (glo_gnav_eph.PRN != 0))
|
||||
{
|
||||
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; // print two messages?
|
||||
}
|
||||
@ -3029,23 +3029,23 @@ std::string Rtcm::print_MSM_6(const Gps_Ephemeris& gps_eph,
|
||||
bool more_messages)
|
||||
{
|
||||
uint32_t msg_number = 0;
|
||||
if (gps_eph.i_satellite_PRN != 0)
|
||||
if (gps_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1076;
|
||||
}
|
||||
if (gps_cnav_eph.i_satellite_PRN != 0)
|
||||
if (gps_cnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1076;
|
||||
}
|
||||
if (glo_gnav_eph.i_satellite_PRN != 0)
|
||||
if (glo_gnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1086;
|
||||
}
|
||||
if (gal_eph.i_satellite_PRN != 0)
|
||||
if (gal_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1096;
|
||||
}
|
||||
if (((gps_eph.i_satellite_PRN != 0) || (gps_cnav_eph.i_satellite_PRN != 0)) && (gal_eph.i_satellite_PRN != 0) && (glo_gnav_eph.i_satellite_PRN != 0))
|
||||
if (((gps_eph.PRN != 0) || (gps_cnav_eph.PRN != 0)) && (gal_eph.PRN != 0) && (glo_gnav_eph.PRN != 0))
|
||||
{
|
||||
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; // print two messages?
|
||||
}
|
||||
@ -3149,23 +3149,23 @@ std::string Rtcm::print_MSM_7(const Gps_Ephemeris& gps_eph,
|
||||
bool more_messages)
|
||||
{
|
||||
uint32_t msg_number = 0;
|
||||
if (gps_eph.i_satellite_PRN != 0)
|
||||
if (gps_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1077;
|
||||
}
|
||||
if (gps_cnav_eph.i_satellite_PRN != 0)
|
||||
if (gps_cnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1077;
|
||||
}
|
||||
if (glo_gnav_eph.i_satellite_PRN != 0)
|
||||
if (glo_gnav_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1087;
|
||||
}
|
||||
if (gal_eph.i_satellite_PRN != 0)
|
||||
if (gal_eph.PRN != 0)
|
||||
{
|
||||
msg_number = 1097;
|
||||
}
|
||||
if (((gps_eph.i_satellite_PRN != 0) || (gps_cnav_eph.i_satellite_PRN != 0)) && (glo_gnav_eph.i_satellite_PRN != 0) && (gal_eph.i_satellite_PRN != 0))
|
||||
if (((gps_eph.PRN != 0) || (gps_cnav_eph.PRN != 0)) && (glo_gnav_eph.PRN != 0) && (gal_eph.PRN != 0))
|
||||
{
|
||||
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; // print two messages?
|
||||
}
|
||||
@ -3391,9 +3391,9 @@ std::map<std::string, int> Rtcm::galileo_signal_map = [] {
|
||||
boost::posix_time::ptime Rtcm::compute_GPS_time(const Gps_Ephemeris& eph, double obs_time) const
|
||||
{
|
||||
const double gps_t = obs_time;
|
||||
const boost::posix_time::time_duration t_duration = boost::posix_time::milliseconds(static_cast<long>((gps_t + 604800 * static_cast<double>(eph.i_GPS_week)) * 1000)); // NOLINT(google-runtime-int)
|
||||
const boost::posix_time::time_duration t_duration = boost::posix_time::milliseconds(static_cast<long>((gps_t + 604800 * static_cast<double>(eph.WN)) * 1000)); // NOLINT(google-runtime-int)
|
||||
|
||||
if (eph.i_GPS_week < 512)
|
||||
if (eph.WN < 512)
|
||||
{
|
||||
boost::posix_time::ptime p_time(boost::gregorian::date(2019, 4, 7), t_duration);
|
||||
return p_time;
|
||||
@ -3407,7 +3407,7 @@ boost::posix_time::ptime Rtcm::compute_GPS_time(const Gps_Ephemeris& eph, double
|
||||
boost::posix_time::ptime Rtcm::compute_GPS_time(const Gps_CNAV_Ephemeris& eph, double obs_time) const
|
||||
{
|
||||
const double gps_t = obs_time;
|
||||
const boost::posix_time::time_duration t_duration = boost::posix_time::milliseconds(static_cast<long>((gps_t + 604800 * static_cast<double>(eph.i_GPS_week)) * 1000)); // NOLINT(google-runtime-int)
|
||||
const boost::posix_time::time_duration t_duration = boost::posix_time::milliseconds(static_cast<long>((gps_t + 604800 * static_cast<double>(eph.WN)) * 1000)); // NOLINT(google-runtime-int)
|
||||
boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t_duration);
|
||||
return p_time;
|
||||
}
|
||||
@ -3416,7 +3416,7 @@ boost::posix_time::ptime Rtcm::compute_GPS_time(const Gps_CNAV_Ephemeris& eph, d
|
||||
boost::posix_time::ptime Rtcm::compute_Galileo_time(const Galileo_Ephemeris& eph, double obs_time) const
|
||||
{
|
||||
const double galileo_t = obs_time;
|
||||
const boost::posix_time::time_duration t_duration = boost::posix_time::milliseconds(static_cast<long>((galileo_t + 604800 * static_cast<double>(eph.WN_5)) * 1000)); // NOLINT(google-runtime-int)
|
||||
const boost::posix_time::time_duration t_duration = boost::posix_time::milliseconds(static_cast<long>((galileo_t + 604800 * static_cast<double>(eph.WN)) * 1000)); // NOLINT(google-runtime-int)
|
||||
boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t_duration);
|
||||
return p_time;
|
||||
}
|
||||
@ -3778,7 +3778,7 @@ int32_t Rtcm::set_DF009(const Gnss_Synchro& gnss_synchro)
|
||||
|
||||
int32_t Rtcm::set_DF009(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const uint32_t prn_ = gps_eph.i_satellite_PRN;
|
||||
const uint32_t prn_ = gps_eph.PRN;
|
||||
if (prn_ > 32)
|
||||
{
|
||||
LOG(WARNING) << "GPS satellite ID must be between 1 and 32, but PRN " << prn_ << " was found";
|
||||
@ -4201,9 +4201,9 @@ int32_t Rtcm::set_DF050(const Gnss_Synchro& gnss_synchro)
|
||||
int32_t Rtcm::set_DF051(const Gps_Ephemeris& gps_eph, double obs_time)
|
||||
{
|
||||
const double gps_t = obs_time;
|
||||
const boost::posix_time::time_duration t_duration = boost::posix_time::milliseconds(static_cast<int64_t>((gps_t + 604800 * static_cast<double>(gps_eph.i_GPS_week)) * 1000));
|
||||
const boost::posix_time::time_duration t_duration = boost::posix_time::milliseconds(static_cast<int64_t>((gps_t + 604800 * static_cast<double>(gps_eph.WN)) * 1000));
|
||||
std::string now_ptime;
|
||||
if (gps_eph.i_GPS_week < 512)
|
||||
if (gps_eph.WN < 512)
|
||||
{
|
||||
boost::posix_time::ptime p_time(boost::gregorian::date(2019, 4, 7), t_duration);
|
||||
now_ptime = to_iso_string(p_time);
|
||||
@ -4224,9 +4224,9 @@ int32_t Rtcm::set_DF051(const Gps_Ephemeris& gps_eph, double obs_time)
|
||||
int32_t Rtcm::set_DF052(const Gps_Ephemeris& gps_eph, double obs_time)
|
||||
{
|
||||
const double gps_t = obs_time;
|
||||
const boost::posix_time::time_duration t_duration = boost::posix_time::milliseconds(static_cast<int64_t>((gps_t + 604800 * static_cast<double>(gps_eph.i_GPS_week)) * 1000));
|
||||
const boost::posix_time::time_duration t_duration = boost::posix_time::milliseconds(static_cast<int64_t>((gps_t + 604800 * static_cast<double>(gps_eph.WN)) * 1000));
|
||||
std::string now_ptime;
|
||||
if (gps_eph.i_GPS_week < 512)
|
||||
if (gps_eph.WN < 512)
|
||||
{
|
||||
boost::posix_time::ptime p_time(boost::gregorian::date(2019, 4, 7), t_duration);
|
||||
now_ptime = to_iso_string(p_time);
|
||||
@ -4248,7 +4248,7 @@ int32_t Rtcm::set_DF052(const Gps_Ephemeris& gps_eph, double obs_time)
|
||||
|
||||
int32_t Rtcm::set_DF071(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto iode = static_cast<uint32_t>(gps_eph.d_IODE_SF2);
|
||||
const auto iode = static_cast<uint32_t>(gps_eph.IODE_SF2);
|
||||
DF071 = std::bitset<8>(iode);
|
||||
return 0;
|
||||
}
|
||||
@ -4256,7 +4256,7 @@ int32_t Rtcm::set_DF071(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF076(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto week_number = static_cast<uint32_t>(gps_eph.i_GPS_week);
|
||||
const auto week_number = static_cast<uint32_t>(gps_eph.WN);
|
||||
DF076 = std::bitset<10>(week_number);
|
||||
return 0;
|
||||
}
|
||||
@ -4264,7 +4264,7 @@ int32_t Rtcm::set_DF076(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF077(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto ura = static_cast<uint16_t>(gps_eph.i_SV_accuracy);
|
||||
const auto ura = static_cast<uint16_t>(gps_eph.SV_accuracy);
|
||||
DF077 = std::bitset<4>(ura);
|
||||
return 0;
|
||||
}
|
||||
@ -4272,7 +4272,7 @@ int32_t Rtcm::set_DF077(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF078(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto code_on_L2 = static_cast<uint16_t>(gps_eph.i_code_on_L2);
|
||||
const auto code_on_L2 = static_cast<uint16_t>(gps_eph.code_on_L2);
|
||||
DF078 = std::bitset<2>(code_on_L2);
|
||||
return 0;
|
||||
}
|
||||
@ -4280,7 +4280,7 @@ int32_t Rtcm::set_DF078(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF079(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto idot = static_cast<uint32_t>(std::round(gps_eph.d_IDOT / I_DOT_LSB));
|
||||
const auto idot = static_cast<uint32_t>(std::round(gps_eph.idot / I_DOT_LSB));
|
||||
DF079 = std::bitset<14>(idot);
|
||||
return 0;
|
||||
}
|
||||
@ -4288,7 +4288,7 @@ int32_t Rtcm::set_DF079(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF080(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto iode = static_cast<uint16_t>(gps_eph.d_IODE_SF2);
|
||||
const auto iode = static_cast<uint16_t>(gps_eph.IODE_SF2);
|
||||
DF080 = std::bitset<8>(iode);
|
||||
return 0;
|
||||
}
|
||||
@ -4296,7 +4296,7 @@ int32_t Rtcm::set_DF080(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF081(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto toc = static_cast<uint32_t>(std::round(gps_eph.d_Toc / T_OC_LSB));
|
||||
const auto toc = static_cast<uint32_t>(std::round(gps_eph.toc / T_OC_LSB));
|
||||
DF081 = std::bitset<16>(toc);
|
||||
return 0;
|
||||
}
|
||||
@ -4304,7 +4304,7 @@ int32_t Rtcm::set_DF081(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF082(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto af2 = static_cast<int16_t>(std::round(gps_eph.d_A_f2 / A_F2_LSB));
|
||||
const auto af2 = static_cast<int16_t>(std::round(gps_eph.af2 / A_F2_LSB));
|
||||
DF082 = std::bitset<8>(af2);
|
||||
return 0;
|
||||
}
|
||||
@ -4312,7 +4312,7 @@ int32_t Rtcm::set_DF082(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF083(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto af1 = static_cast<int32_t>(std::round(gps_eph.d_A_f1 / A_F1_LSB));
|
||||
const auto af1 = static_cast<int32_t>(std::round(gps_eph.af1 / A_F1_LSB));
|
||||
DF083 = std::bitset<16>(af1);
|
||||
return 0;
|
||||
}
|
||||
@ -4320,7 +4320,7 @@ int32_t Rtcm::set_DF083(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF084(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto af0 = static_cast<int64_t>(std::round(gps_eph.d_A_f0 / A_F0_LSB));
|
||||
const auto af0 = static_cast<int64_t>(std::round(gps_eph.af0 / A_F0_LSB));
|
||||
DF084 = std::bitset<22>(af0);
|
||||
return 0;
|
||||
}
|
||||
@ -4328,7 +4328,7 @@ int32_t Rtcm::set_DF084(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF085(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto iodc = static_cast<uint32_t>(gps_eph.d_IODC);
|
||||
const auto iodc = static_cast<uint32_t>(gps_eph.IODC);
|
||||
DF085 = std::bitset<10>(iodc);
|
||||
return 0;
|
||||
}
|
||||
@ -4336,7 +4336,7 @@ int32_t Rtcm::set_DF085(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF086(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto crs = static_cast<int32_t>(std::round(gps_eph.d_Crs / C_RS_LSB));
|
||||
const auto crs = static_cast<int32_t>(std::round(gps_eph.Crs / C_RS_LSB));
|
||||
DF086 = std::bitset<16>(crs);
|
||||
return 0;
|
||||
}
|
||||
@ -4344,7 +4344,7 @@ int32_t Rtcm::set_DF086(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF087(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto delta_n = static_cast<int32_t>(std::round(gps_eph.d_Delta_n / DELTA_N_LSB));
|
||||
const auto delta_n = static_cast<int32_t>(std::round(gps_eph.delta_n / DELTA_N_LSB));
|
||||
DF087 = std::bitset<16>(delta_n);
|
||||
return 0;
|
||||
}
|
||||
@ -4352,7 +4352,7 @@ int32_t Rtcm::set_DF087(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF088(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto m0 = static_cast<int64_t>(std::round(gps_eph.d_M_0 / M_0_LSB));
|
||||
const auto m0 = static_cast<int64_t>(std::round(gps_eph.M_0 / M_0_LSB));
|
||||
DF088 = std::bitset<32>(m0);
|
||||
return 0;
|
||||
}
|
||||
@ -4360,14 +4360,14 @@ int32_t Rtcm::set_DF088(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF089(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto cuc = static_cast<int32_t>(std::round(gps_eph.d_Cuc / C_UC_LSB));
|
||||
const auto cuc = static_cast<int32_t>(std::round(gps_eph.Cuc / C_UC_LSB));
|
||||
DF089 = std::bitset<16>(cuc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Rtcm::set_DF090(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto ecc = static_cast<uint64_t>(std::round(gps_eph.d_e_eccentricity / ECCENTRICITY_LSB));
|
||||
const auto ecc = static_cast<uint64_t>(std::round(gps_eph.ecc / ECCENTRICITY_LSB));
|
||||
DF090 = std::bitset<32>(ecc);
|
||||
return 0;
|
||||
}
|
||||
@ -4375,7 +4375,7 @@ int32_t Rtcm::set_DF090(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF091(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto cus = static_cast<int32_t>(std::round(gps_eph.d_Cus / C_US_LSB));
|
||||
const auto cus = static_cast<int32_t>(std::round(gps_eph.Cus / C_US_LSB));
|
||||
DF091 = std::bitset<16>(cus);
|
||||
return 0;
|
||||
}
|
||||
@ -4383,7 +4383,7 @@ int32_t Rtcm::set_DF091(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF092(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto sqr_a = static_cast<uint64_t>(std::round(gps_eph.d_sqrt_A / SQRT_A_LSB));
|
||||
const auto sqr_a = static_cast<uint64_t>(std::round(gps_eph.sqrtA / SQRT_A_LSB));
|
||||
DF092 = std::bitset<32>(sqr_a);
|
||||
return 0;
|
||||
}
|
||||
@ -4391,7 +4391,7 @@ int32_t Rtcm::set_DF092(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF093(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto toe = static_cast<uint32_t>(std::round(gps_eph.d_Toe / T_OE_LSB));
|
||||
const auto toe = static_cast<uint32_t>(std::round(gps_eph.toe / T_OE_LSB));
|
||||
DF093 = std::bitset<16>(toe);
|
||||
return 0;
|
||||
}
|
||||
@ -4399,7 +4399,7 @@ int32_t Rtcm::set_DF093(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF094(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto cic = static_cast<int32_t>(std::round(gps_eph.d_Cic / C_IC_LSB));
|
||||
const auto cic = static_cast<int32_t>(std::round(gps_eph.Cic / C_IC_LSB));
|
||||
DF094 = std::bitset<16>(cic);
|
||||
return 0;
|
||||
}
|
||||
@ -4407,7 +4407,7 @@ int32_t Rtcm::set_DF094(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF095(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto Omega0 = static_cast<int64_t>(std::round(gps_eph.d_OMEGA0 / OMEGA_0_LSB));
|
||||
const auto Omega0 = static_cast<int64_t>(std::round(gps_eph.OMEGA_0 / OMEGA_0_LSB));
|
||||
DF095 = std::bitset<32>(Omega0);
|
||||
return 0;
|
||||
}
|
||||
@ -4415,7 +4415,7 @@ int32_t Rtcm::set_DF095(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF096(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto cis = static_cast<int32_t>(std::round(gps_eph.d_Cis / C_IS_LSB));
|
||||
const auto cis = static_cast<int32_t>(std::round(gps_eph.Cis / C_IS_LSB));
|
||||
DF096 = std::bitset<16>(cis);
|
||||
return 0;
|
||||
}
|
||||
@ -4423,7 +4423,7 @@ int32_t Rtcm::set_DF096(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF097(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto i0 = static_cast<int64_t>(std::round(gps_eph.d_i_0 / I_0_LSB));
|
||||
const auto i0 = static_cast<int64_t>(std::round(gps_eph.i_0 / I_0_LSB));
|
||||
DF097 = std::bitset<32>(i0);
|
||||
return 0;
|
||||
}
|
||||
@ -4431,7 +4431,7 @@ int32_t Rtcm::set_DF097(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF098(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto crc = static_cast<int32_t>(std::round(gps_eph.d_Crc / C_RC_LSB));
|
||||
const auto crc = static_cast<int32_t>(std::round(gps_eph.Crc / C_RC_LSB));
|
||||
DF098 = std::bitset<16>(crc);
|
||||
return 0;
|
||||
}
|
||||
@ -4439,7 +4439,7 @@ int32_t Rtcm::set_DF098(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF099(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto omega = static_cast<int64_t>(std::round(gps_eph.d_OMEGA / OMEGA_LSB));
|
||||
const auto omega = static_cast<int64_t>(std::round(gps_eph.omega / OMEGA_LSB));
|
||||
DF099 = std::bitset<32>(omega);
|
||||
return 0;
|
||||
}
|
||||
@ -4447,7 +4447,7 @@ int32_t Rtcm::set_DF099(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF100(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto omegadot = static_cast<int64_t>(std::round(gps_eph.d_OMEGA_DOT / OMEGA_DOT_LSB));
|
||||
const auto omegadot = static_cast<int64_t>(std::round(gps_eph.OMEGAdot / OMEGA_DOT_LSB));
|
||||
DF100 = std::bitset<24>(omegadot);
|
||||
return 0;
|
||||
}
|
||||
@ -4455,7 +4455,7 @@ int32_t Rtcm::set_DF100(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF101(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto tgd = static_cast<int16_t>(std::round(gps_eph.d_TGD / T_GD_LSB));
|
||||
const auto tgd = static_cast<int16_t>(std::round(gps_eph.TGD / T_GD_LSB));
|
||||
DF101 = std::bitset<8>(tgd);
|
||||
return 0;
|
||||
}
|
||||
@ -4463,7 +4463,7 @@ int32_t Rtcm::set_DF101(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF102(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
const auto sv_heath = static_cast<uint16_t>(gps_eph.i_SV_health);
|
||||
const auto sv_heath = static_cast<uint16_t>(gps_eph.SV_health);
|
||||
DF102 = std::bitset<6>(sv_heath);
|
||||
return 0;
|
||||
}
|
||||
@ -4471,7 +4471,7 @@ int32_t Rtcm::set_DF102(const Gps_Ephemeris& gps_eph)
|
||||
|
||||
int32_t Rtcm::set_DF103(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
DF103 = std::bitset<1>(gps_eph.b_L2_P_data_flag);
|
||||
DF103 = std::bitset<1>(gps_eph.L2_P_data_flag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4789,7 +4789,7 @@ int32_t Rtcm::set_DF136(const Glonass_Gnav_Ephemeris& glonass_gnav_eph)
|
||||
|
||||
int32_t Rtcm::set_DF137(const Gps_Ephemeris& gps_eph)
|
||||
{
|
||||
DF137 = std::bitset<1>(gps_eph.b_fit_interval_flag);
|
||||
DF137 = std::bitset<1>(gps_eph.fit_interval_flag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4810,7 +4810,7 @@ int32_t Rtcm::set_DF248(double obs_time)
|
||||
|
||||
int32_t Rtcm::set_DF252(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const uint32_t prn_ = gal_eph.i_satellite_PRN;
|
||||
const uint32_t prn_ = gal_eph.PRN;
|
||||
if (prn_ > 63)
|
||||
{
|
||||
LOG(WARNING) << "Galileo satellite ID must be between 0 and 63, but PRN " << prn_ << " was found";
|
||||
@ -4822,7 +4822,7 @@ int32_t Rtcm::set_DF252(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF289(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto galileo_week_number = static_cast<uint32_t>(gal_eph.WN_5);
|
||||
const auto galileo_week_number = static_cast<uint32_t>(gal_eph.WN);
|
||||
if (galileo_week_number > 4095)
|
||||
{
|
||||
LOG(WARNING) << "Error decoding Galileo week number (it has a 4096 roll-off, but " << galileo_week_number << " was detected)";
|
||||
@ -4834,7 +4834,7 @@ int32_t Rtcm::set_DF289(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF290(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto iod_nav = static_cast<uint32_t>(gal_eph.IOD_nav_1);
|
||||
const auto iod_nav = static_cast<uint32_t>(gal_eph.IOD_nav);
|
||||
if (iod_nav > 1023)
|
||||
{
|
||||
LOG(WARNING) << "Error decoding Galileo IODnav (it has a max of 1023, but " << iod_nav << " was detected)";
|
||||
@ -4846,7 +4846,7 @@ int32_t Rtcm::set_DF290(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF291(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto SISA = static_cast<uint16_t>(gal_eph.SISA_3);
|
||||
const auto SISA = static_cast<uint16_t>(gal_eph.SISA);
|
||||
// SISA = 0; // SIS Accuracy, data content definition not given in Galileo OS SIS ICD, Issue 1.1, Sept 2010
|
||||
DF291 = std::bitset<8>(SISA);
|
||||
return 0;
|
||||
@ -4855,7 +4855,7 @@ int32_t Rtcm::set_DF291(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF292(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto idot = static_cast<int32_t>(std::round(gal_eph.iDot_2 / FNAV_IDOT_2_LSB));
|
||||
const auto idot = static_cast<int32_t>(std::round(gal_eph.idot / FNAV_IDOT_2_LSB));
|
||||
DF292 = std::bitset<14>(idot);
|
||||
return 0;
|
||||
}
|
||||
@ -4863,7 +4863,7 @@ int32_t Rtcm::set_DF292(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF293(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto toc = static_cast<uint32_t>(gal_eph.t0c_4);
|
||||
const auto toc = static_cast<uint32_t>(gal_eph.toc);
|
||||
if (toc > 604740)
|
||||
{
|
||||
LOG(WARNING) << "Error decoding Galileo ephemeris time (max of 604740, but " << toc << " was detected)";
|
||||
@ -4875,7 +4875,7 @@ int32_t Rtcm::set_DF293(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF294(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto af2 = static_cast<int16_t>(std::round(gal_eph.af2_4 / FNAV_AF2_1_LSB));
|
||||
const auto af2 = static_cast<int16_t>(std::round(gal_eph.af2 / FNAV_AF2_1_LSB));
|
||||
DF294 = std::bitset<6>(af2);
|
||||
return 0;
|
||||
}
|
||||
@ -4883,7 +4883,7 @@ int32_t Rtcm::set_DF294(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF295(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto af1 = static_cast<int64_t>(std::round(gal_eph.af1_4 / FNAV_AF1_1_LSB));
|
||||
const auto af1 = static_cast<int64_t>(std::round(gal_eph.af1 / FNAV_AF1_1_LSB));
|
||||
DF295 = std::bitset<21>(af1);
|
||||
return 0;
|
||||
}
|
||||
@ -4891,7 +4891,7 @@ int32_t Rtcm::set_DF295(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF296(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const int64_t af0 = static_cast<uint32_t>(std::round(gal_eph.af0_4 / FNAV_AF0_1_LSB));
|
||||
const int64_t af0 = static_cast<uint32_t>(std::round(gal_eph.af0 / FNAV_AF0_1_LSB));
|
||||
DF296 = std::bitset<31>(af0);
|
||||
return 0;
|
||||
}
|
||||
@ -4899,7 +4899,7 @@ int32_t Rtcm::set_DF296(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF297(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto crs = static_cast<int32_t>(std::round(gal_eph.C_rs_3 / FNAV_CRS_3_LSB));
|
||||
const auto crs = static_cast<int32_t>(std::round(gal_eph.Crs / FNAV_CRS_3_LSB));
|
||||
DF297 = std::bitset<16>(crs);
|
||||
return 0;
|
||||
}
|
||||
@ -4907,7 +4907,7 @@ int32_t Rtcm::set_DF297(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF298(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto delta_n = static_cast<int32_t>(std::round(gal_eph.delta_n_3 / FNAV_DELTAN_3_LSB));
|
||||
const auto delta_n = static_cast<int32_t>(std::round(gal_eph.delta_n / FNAV_DELTAN_3_LSB));
|
||||
DF298 = std::bitset<16>(delta_n);
|
||||
return 0;
|
||||
}
|
||||
@ -4915,7 +4915,7 @@ int32_t Rtcm::set_DF298(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF299(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto m0 = static_cast<int64_t>(std::round(gal_eph.M0_1 / FNAV_M0_2_LSB));
|
||||
const auto m0 = static_cast<int64_t>(std::round(gal_eph.M_0 / FNAV_M0_2_LSB));
|
||||
DF299 = std::bitset<32>(m0);
|
||||
return 0;
|
||||
}
|
||||
@ -4923,7 +4923,7 @@ int32_t Rtcm::set_DF299(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF300(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const int32_t cuc = static_cast<uint32_t>(std::round(gal_eph.C_uc_3 / FNAV_CUC_3_LSB));
|
||||
const int32_t cuc = static_cast<uint32_t>(std::round(gal_eph.Cuc / FNAV_CUC_3_LSB));
|
||||
DF300 = std::bitset<16>(cuc);
|
||||
return 0;
|
||||
}
|
||||
@ -4931,7 +4931,7 @@ int32_t Rtcm::set_DF300(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF301(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto ecc = static_cast<uint64_t>(std::round(gal_eph.e_1 / FNAV_E_2_LSB));
|
||||
const auto ecc = static_cast<uint64_t>(std::round(gal_eph.ecc / FNAV_E_2_LSB));
|
||||
DF301 = std::bitset<32>(ecc);
|
||||
return 0;
|
||||
}
|
||||
@ -4939,7 +4939,7 @@ int32_t Rtcm::set_DF301(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF302(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto cus = static_cast<int32_t>(std::round(gal_eph.C_us_3 / FNAV_CUS_3_LSB));
|
||||
const auto cus = static_cast<int32_t>(std::round(gal_eph.Cus / FNAV_CUS_3_LSB));
|
||||
DF302 = std::bitset<16>(cus);
|
||||
return 0;
|
||||
}
|
||||
@ -4947,7 +4947,7 @@ int32_t Rtcm::set_DF302(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF303(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto sqr_a = static_cast<uint64_t>(std::round(gal_eph.A_1 / FNAV_A12_2_LSB));
|
||||
const auto sqr_a = static_cast<uint64_t>(std::round(gal_eph.sqrtA / FNAV_A12_2_LSB));
|
||||
DF303 = std::bitset<32>(sqr_a);
|
||||
return 0;
|
||||
}
|
||||
@ -4955,7 +4955,7 @@ int32_t Rtcm::set_DF303(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF304(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto toe = static_cast<uint32_t>(std::round(gal_eph.t0e_1 / FNAV_T0E_3_LSB));
|
||||
const auto toe = static_cast<uint32_t>(std::round(gal_eph.toe / FNAV_T0E_3_LSB));
|
||||
DF304 = std::bitset<14>(toe);
|
||||
return 0;
|
||||
}
|
||||
@ -4963,7 +4963,7 @@ int32_t Rtcm::set_DF304(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF305(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto cic = static_cast<int32_t>(std::round(gal_eph.C_ic_4 / FNAV_CIC_4_LSB));
|
||||
const auto cic = static_cast<int32_t>(std::round(gal_eph.Cic / FNAV_CIC_4_LSB));
|
||||
DF305 = std::bitset<16>(cic);
|
||||
return 0;
|
||||
}
|
||||
@ -4971,7 +4971,7 @@ int32_t Rtcm::set_DF305(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF306(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto Omega0 = static_cast<int64_t>(std::round(gal_eph.OMEGA_0_2 / FNAV_OMEGA0_2_LSB));
|
||||
const auto Omega0 = static_cast<int64_t>(std::round(gal_eph.OMEGA_0 / FNAV_OMEGA0_2_LSB));
|
||||
DF306 = std::bitset<32>(Omega0);
|
||||
return 0;
|
||||
}
|
||||
@ -4979,7 +4979,7 @@ int32_t Rtcm::set_DF306(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF307(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto cis = static_cast<int32_t>(std::round(gal_eph.C_is_4 / FNAV_CIS_4_LSB));
|
||||
const auto cis = static_cast<int32_t>(std::round(gal_eph.Cis / FNAV_CIS_4_LSB));
|
||||
DF307 = std::bitset<16>(cis);
|
||||
return 0;
|
||||
}
|
||||
@ -4987,7 +4987,7 @@ int32_t Rtcm::set_DF307(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF308(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto i0 = static_cast<int64_t>(std::round(gal_eph.i_0_2 / FNAV_I0_3_LSB));
|
||||
const auto i0 = static_cast<int64_t>(std::round(gal_eph.i_0 / FNAV_I0_3_LSB));
|
||||
DF308 = std::bitset<32>(i0);
|
||||
return 0;
|
||||
}
|
||||
@ -4995,7 +4995,7 @@ int32_t Rtcm::set_DF308(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF309(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const int32_t crc = static_cast<uint32_t>(std::round(gal_eph.C_rc_3 / FNAV_CRC_3_LSB));
|
||||
const int32_t crc = static_cast<uint32_t>(std::round(gal_eph.Crc / FNAV_CRC_3_LSB));
|
||||
DF309 = std::bitset<16>(crc);
|
||||
return 0;
|
||||
}
|
||||
@ -5003,7 +5003,7 @@ int32_t Rtcm::set_DF309(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF310(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto omega = static_cast<int32_t>(std::round(gal_eph.omega_2 / FNAV_OMEGA0_2_LSB));
|
||||
const auto omega = static_cast<int32_t>(std::round(gal_eph.omega / FNAV_OMEGA0_2_LSB));
|
||||
DF310 = std::bitset<32>(omega);
|
||||
return 0;
|
||||
}
|
||||
@ -5011,7 +5011,7 @@ int32_t Rtcm::set_DF310(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF311(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto Omegadot = static_cast<int64_t>(std::round(gal_eph.OMEGA_dot_3 / FNAV_OMEGADOT_2_LSB));
|
||||
const auto Omegadot = static_cast<int64_t>(std::round(gal_eph.OMEGAdot / FNAV_OMEGADOT_2_LSB));
|
||||
DF311 = std::bitset<24>(Omegadot);
|
||||
return 0;
|
||||
}
|
||||
@ -5019,7 +5019,7 @@ int32_t Rtcm::set_DF311(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF312(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto bdg_E1_E5a = static_cast<int32_t>(std::round(gal_eph.BGD_E1E5a_5 / FNAV_BGD_1_LSB));
|
||||
const auto bdg_E1_E5a = static_cast<int32_t>(std::round(gal_eph.BGD_E1E5a / FNAV_BGD_1_LSB));
|
||||
DF312 = std::bitset<10>(bdg_E1_E5a);
|
||||
return 0;
|
||||
}
|
||||
@ -5027,7 +5027,7 @@ int32_t Rtcm::set_DF312(const Galileo_Ephemeris& gal_eph)
|
||||
|
||||
int32_t Rtcm::set_DF313(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
const auto bdg_E5b_E1 = static_cast<uint32_t>(std::round(gal_eph.BGD_E1E5b_5));
|
||||
const auto bdg_E5b_E1 = static_cast<uint32_t>(std::round(gal_eph.BGD_E1E5b));
|
||||
// bdg_E5b_E1 = 0; // reserved
|
||||
DF313 = std::bitset<10>(bdg_E5b_E1);
|
||||
return 0;
|
||||
|
@ -457,7 +457,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
obsd_t newobs{};
|
||||
obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
galileo_ephemeris_iter->second.WN_5,
|
||||
galileo_ephemeris_iter->second.WN,
|
||||
0);
|
||||
valid_obs++;
|
||||
}
|
||||
@ -481,7 +481,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{
|
||||
obs_data[i + glo_valid_obs] = insert_obs_to_rtklib(obs_data[i + glo_valid_obs],
|
||||
gnss_observables_iter->second,
|
||||
galileo_ephemeris_iter->second.WN_5,
|
||||
galileo_ephemeris_iter->second.WN,
|
||||
2); // Band 3 (L5/E5)
|
||||
found_E1_obs = true;
|
||||
break;
|
||||
@ -499,7 +499,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{}, {0.0, 0.0, 0.0}, {}};
|
||||
obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
galileo_ephemeris_iter->second.WN_5,
|
||||
galileo_ephemeris_iter->second.WN,
|
||||
2); // Band 3 (L5/E5)
|
||||
valid_obs++;
|
||||
}
|
||||
@ -527,7 +527,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
obsd_t newobs{};
|
||||
obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
gps_ephemeris_iter->second.i_GPS_week,
|
||||
gps_ephemeris_iter->second.WN,
|
||||
0,
|
||||
this->is_pre_2009());
|
||||
valid_obs++;
|
||||
@ -576,7 +576,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{}, {0.0, 0.0, 0.0}, {}};
|
||||
obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
gps_cnav_ephemeris_iter->second.i_GPS_week,
|
||||
gps_cnav_ephemeris_iter->second.WN,
|
||||
1); // Band 2 (L2)
|
||||
valid_obs++;
|
||||
}
|
||||
@ -605,7 +605,7 @@ 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],
|
||||
gnss_observables_iter->second,
|
||||
gps_cnav_ephemeris_iter->second.i_GPS_week,
|
||||
gps_cnav_ephemeris_iter->second.WN,
|
||||
2); // Band 3 (L5)
|
||||
break;
|
||||
}
|
||||
@ -623,7 +623,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{}, {0.0, 0.0, 0.0}, {}};
|
||||
obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
gps_cnav_ephemeris_iter->second.i_GPS_week,
|
||||
gps_cnav_ephemeris_iter->second.WN,
|
||||
2); // Band 3 (L5)
|
||||
valid_obs++;
|
||||
}
|
||||
@ -717,7 +717,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
obsd_t newobs{};
|
||||
obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
beidou_ephemeris_iter->second.i_BEIDOU_week + BEIDOU_DNAV_BDT2GPST_WEEK_NUM_OFFSET,
|
||||
beidou_ephemeris_iter->second.WN + BEIDOU_DNAV_BDT2GPST_WEEK_NUM_OFFSET,
|
||||
0);
|
||||
valid_obs++;
|
||||
}
|
||||
@ -739,7 +739,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{
|
||||
obs_data[i + glo_valid_obs] = insert_obs_to_rtklib(obs_data[i + glo_valid_obs],
|
||||
gnss_observables_iter->second,
|
||||
beidou_ephemeris_iter->second.i_BEIDOU_week + BEIDOU_DNAV_BDT2GPST_WEEK_NUM_OFFSET,
|
||||
beidou_ephemeris_iter->second.WN + BEIDOU_DNAV_BDT2GPST_WEEK_NUM_OFFSET,
|
||||
2); // Band 3 (L2/G2/B3)
|
||||
found_B1I_obs = true;
|
||||
break;
|
||||
@ -757,7 +757,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{}, {0.0, 0.0, 0.0}, {}};
|
||||
obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
beidou_ephemeris_iter->second.i_BEIDOU_week + BEIDOU_DNAV_BDT2GPST_WEEK_NUM_OFFSET,
|
||||
beidou_ephemeris_iter->second.WN + BEIDOU_DNAV_BDT2GPST_WEEK_NUM_OFFSET,
|
||||
2); // Band 2 (L2/G2)
|
||||
valid_obs++;
|
||||
}
|
||||
@ -791,59 +791,59 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
nav_data.ng = glo_valid_obs;
|
||||
if (gps_iono.valid)
|
||||
{
|
||||
nav_data.ion_gps[0] = gps_iono.d_alpha0;
|
||||
nav_data.ion_gps[1] = gps_iono.d_alpha1;
|
||||
nav_data.ion_gps[2] = gps_iono.d_alpha2;
|
||||
nav_data.ion_gps[3] = gps_iono.d_alpha3;
|
||||
nav_data.ion_gps[4] = gps_iono.d_beta0;
|
||||
nav_data.ion_gps[5] = gps_iono.d_beta1;
|
||||
nav_data.ion_gps[6] = gps_iono.d_beta2;
|
||||
nav_data.ion_gps[7] = gps_iono.d_beta3;
|
||||
nav_data.ion_gps[0] = gps_iono.alpha0;
|
||||
nav_data.ion_gps[1] = gps_iono.alpha1;
|
||||
nav_data.ion_gps[2] = gps_iono.alpha2;
|
||||
nav_data.ion_gps[3] = gps_iono.alpha3;
|
||||
nav_data.ion_gps[4] = gps_iono.beta0;
|
||||
nav_data.ion_gps[5] = gps_iono.beta1;
|
||||
nav_data.ion_gps[6] = gps_iono.beta2;
|
||||
nav_data.ion_gps[7] = gps_iono.beta3;
|
||||
}
|
||||
if (!(gps_iono.valid) and gps_cnav_iono.valid)
|
||||
{
|
||||
nav_data.ion_gps[0] = gps_cnav_iono.d_alpha0;
|
||||
nav_data.ion_gps[1] = gps_cnav_iono.d_alpha1;
|
||||
nav_data.ion_gps[2] = gps_cnav_iono.d_alpha2;
|
||||
nav_data.ion_gps[3] = gps_cnav_iono.d_alpha3;
|
||||
nav_data.ion_gps[4] = gps_cnav_iono.d_beta0;
|
||||
nav_data.ion_gps[5] = gps_cnav_iono.d_beta1;
|
||||
nav_data.ion_gps[6] = gps_cnav_iono.d_beta2;
|
||||
nav_data.ion_gps[7] = gps_cnav_iono.d_beta3;
|
||||
nav_data.ion_gps[0] = gps_cnav_iono.alpha0;
|
||||
nav_data.ion_gps[1] = gps_cnav_iono.alpha1;
|
||||
nav_data.ion_gps[2] = gps_cnav_iono.alpha2;
|
||||
nav_data.ion_gps[3] = gps_cnav_iono.alpha3;
|
||||
nav_data.ion_gps[4] = gps_cnav_iono.beta0;
|
||||
nav_data.ion_gps[5] = gps_cnav_iono.beta1;
|
||||
nav_data.ion_gps[6] = gps_cnav_iono.beta2;
|
||||
nav_data.ion_gps[7] = gps_cnav_iono.beta3;
|
||||
}
|
||||
if (galileo_iono.ai0_5 != 0.0)
|
||||
if (galileo_iono.ai0 != 0.0)
|
||||
{
|
||||
nav_data.ion_gal[0] = galileo_iono.ai0_5;
|
||||
nav_data.ion_gal[1] = galileo_iono.ai1_5;
|
||||
nav_data.ion_gal[2] = galileo_iono.ai2_5;
|
||||
nav_data.ion_gal[0] = galileo_iono.ai0;
|
||||
nav_data.ion_gal[1] = galileo_iono.ai1;
|
||||
nav_data.ion_gal[2] = galileo_iono.ai2;
|
||||
nav_data.ion_gal[3] = 0.0;
|
||||
}
|
||||
if (beidou_dnav_iono.valid)
|
||||
{
|
||||
nav_data.ion_cmp[0] = beidou_dnav_iono.d_alpha0;
|
||||
nav_data.ion_cmp[1] = beidou_dnav_iono.d_alpha1;
|
||||
nav_data.ion_cmp[2] = beidou_dnav_iono.d_alpha2;
|
||||
nav_data.ion_cmp[3] = beidou_dnav_iono.d_alpha3;
|
||||
nav_data.ion_cmp[4] = beidou_dnav_iono.d_beta0;
|
||||
nav_data.ion_cmp[5] = beidou_dnav_iono.d_beta0;
|
||||
nav_data.ion_cmp[6] = beidou_dnav_iono.d_beta0;
|
||||
nav_data.ion_cmp[7] = beidou_dnav_iono.d_beta3;
|
||||
nav_data.ion_cmp[0] = beidou_dnav_iono.alpha0;
|
||||
nav_data.ion_cmp[1] = beidou_dnav_iono.alpha1;
|
||||
nav_data.ion_cmp[2] = beidou_dnav_iono.alpha2;
|
||||
nav_data.ion_cmp[3] = beidou_dnav_iono.alpha3;
|
||||
nav_data.ion_cmp[4] = beidou_dnav_iono.beta0;
|
||||
nav_data.ion_cmp[5] = beidou_dnav_iono.beta0;
|
||||
nav_data.ion_cmp[6] = beidou_dnav_iono.beta0;
|
||||
nav_data.ion_cmp[7] = beidou_dnav_iono.beta3;
|
||||
}
|
||||
if (gps_utc_model.valid)
|
||||
{
|
||||
nav_data.utc_gps[0] = gps_utc_model.d_A0;
|
||||
nav_data.utc_gps[1] = gps_utc_model.d_A1;
|
||||
nav_data.utc_gps[2] = gps_utc_model.d_t_OT;
|
||||
nav_data.utc_gps[3] = gps_utc_model.i_WN_T;
|
||||
nav_data.leaps = gps_utc_model.d_DeltaT_LS;
|
||||
nav_data.utc_gps[0] = gps_utc_model.A0;
|
||||
nav_data.utc_gps[1] = gps_utc_model.A1;
|
||||
nav_data.utc_gps[2] = gps_utc_model.tot;
|
||||
nav_data.utc_gps[3] = gps_utc_model.WN_T;
|
||||
nav_data.leaps = gps_utc_model.DeltaT_LS;
|
||||
}
|
||||
if (!(gps_utc_model.valid) and gps_cnav_utc_model.valid)
|
||||
{
|
||||
nav_data.utc_gps[0] = gps_cnav_utc_model.d_A0;
|
||||
nav_data.utc_gps[1] = gps_cnav_utc_model.d_A1;
|
||||
nav_data.utc_gps[2] = gps_cnav_utc_model.d_t_OT;
|
||||
nav_data.utc_gps[3] = gps_cnav_utc_model.i_WN_T;
|
||||
nav_data.leaps = gps_cnav_utc_model.d_DeltaT_LS;
|
||||
nav_data.utc_gps[0] = gps_cnav_utc_model.A0;
|
||||
nav_data.utc_gps[1] = gps_cnav_utc_model.A1;
|
||||
nav_data.utc_gps[2] = gps_cnav_utc_model.tot;
|
||||
nav_data.utc_gps[3] = gps_cnav_utc_model.WN_T;
|
||||
nav_data.leaps = gps_cnav_utc_model.DeltaT_LS;
|
||||
}
|
||||
if (glonass_gnav_utc_model.valid)
|
||||
{
|
||||
@ -852,21 +852,21 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
nav_data.utc_glo[2] = 0.0; // ??
|
||||
nav_data.utc_glo[3] = 0.0; // ??
|
||||
}
|
||||
if (galileo_utc_model.A0_6 != 0.0)
|
||||
if (galileo_utc_model.A0 != 0.0)
|
||||
{
|
||||
nav_data.utc_gal[0] = galileo_utc_model.A0_6;
|
||||
nav_data.utc_gal[1] = galileo_utc_model.A1_6;
|
||||
nav_data.utc_gal[2] = galileo_utc_model.t0t_6;
|
||||
nav_data.utc_gal[3] = galileo_utc_model.WNot_6;
|
||||
nav_data.leaps = galileo_utc_model.Delta_tLS_6;
|
||||
nav_data.utc_gal[0] = galileo_utc_model.A0;
|
||||
nav_data.utc_gal[1] = galileo_utc_model.A1;
|
||||
nav_data.utc_gal[2] = galileo_utc_model.tot;
|
||||
nav_data.utc_gal[3] = galileo_utc_model.WNot;
|
||||
nav_data.leaps = galileo_utc_model.Delta_tLS;
|
||||
}
|
||||
if (beidou_dnav_utc_model.valid)
|
||||
{
|
||||
nav_data.utc_cmp[0] = beidou_dnav_utc_model.d_A0_UTC;
|
||||
nav_data.utc_cmp[1] = beidou_dnav_utc_model.d_A1_UTC;
|
||||
nav_data.utc_cmp[0] = beidou_dnav_utc_model.A0_UTC;
|
||||
nav_data.utc_cmp[1] = beidou_dnav_utc_model.A1_UTC;
|
||||
nav_data.utc_cmp[2] = 0.0; // ??
|
||||
nav_data.utc_cmp[3] = 0.0; // ??
|
||||
nav_data.leaps = beidou_dnav_utc_model.i_DeltaT_LS;
|
||||
nav_data.leaps = beidou_dnav_utc_model.DeltaT_LS;
|
||||
}
|
||||
|
||||
/* update carrier wave length using native function call in RTKlib */
|
||||
|
179
src/algorithms/PVT/libs/serdes_galileo_eph.h
Normal file
179
src/algorithms/PVT/libs/serdes_galileo_eph.h
Normal file
@ -0,0 +1,179 @@
|
||||
/*!
|
||||
* \file serdes_galileo_eph.h
|
||||
* \brief Serialization / Deserialization of Galileo_Ephemeris objects using
|
||||
* Protocol Buffers
|
||||
* \author Javier Arribas, 2021. jarribas(at)cttc.es
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_SERDES_GALILEO_EPH_H
|
||||
#define GNSS_SDR_SERDES_GALILEO_EPH_H
|
||||
|
||||
#include "galileo_ephemeris.h"
|
||||
#include "galileo_ephemeris.pb.h" // file created by Protocol Buffers at compile time
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
/** \addtogroup PVT
|
||||
* \{ */
|
||||
/** \addtogroup PVT_libs
|
||||
* \{ */
|
||||
|
||||
|
||||
/*!
|
||||
* \brief This class implements serialization and deserialization of
|
||||
* Galileo_Ephemeris using Protocol Buffers.
|
||||
*/
|
||||
class Serdes_Galileo_Eph
|
||||
{
|
||||
public:
|
||||
Serdes_Galileo_Eph()
|
||||
{
|
||||
// Verify that the version of the library that we linked against is
|
||||
// compatible with the version of the headers we compiled against.
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
}
|
||||
|
||||
~Serdes_Galileo_Eph()
|
||||
{
|
||||
// google::protobuf::ShutdownProtobufLibrary();
|
||||
}
|
||||
|
||||
inline Serdes_Galileo_Eph(const Serdes_Galileo_Eph& other) noexcept //!< Copy constructor
|
||||
{
|
||||
this->monitor_ = other.monitor_;
|
||||
}
|
||||
|
||||
inline Serdes_Galileo_Eph& operator=(const Serdes_Galileo_Eph& rhs) noexcept //!< Copy assignment operator
|
||||
{
|
||||
this->monitor_ = rhs.monitor_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Serdes_Galileo_Eph(Serdes_Galileo_Eph&& other) noexcept //!< Move constructor
|
||||
{
|
||||
this->monitor_ = std::move(other.monitor_);
|
||||
}
|
||||
|
||||
inline Serdes_Galileo_Eph& operator=(Serdes_Galileo_Eph&& other) noexcept //!< Move assignment operator
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
this->monitor_ = std::move(other.monitor_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline std::string createProtobuffer(const std::shared_ptr<Galileo_Ephemeris> monitor) //!< Serialization into a string
|
||||
{
|
||||
monitor_.Clear();
|
||||
|
||||
std::string data;
|
||||
|
||||
monitor_.set_prn(monitor->PRN);
|
||||
monitor_.set_m_0(monitor->M_0);
|
||||
monitor_.set_delta_n(monitor->delta_n);
|
||||
monitor_.set_ecc(monitor->ecc);
|
||||
monitor_.set_sqrta(monitor->sqrtA);
|
||||
monitor_.set_omega_0(monitor->OMEGA_0);
|
||||
monitor_.set_i_0(monitor->i_0);
|
||||
monitor_.set_omega(monitor->omega);
|
||||
monitor_.set_omegadot(monitor->OMEGAdot);
|
||||
monitor_.set_idot(monitor->idot);
|
||||
monitor_.set_cuc(monitor->Cuc);
|
||||
monitor_.set_cus(monitor->Cus);
|
||||
monitor_.set_crc(monitor->Crc);
|
||||
monitor_.set_crs(monitor->Crs);
|
||||
monitor_.set_cic(monitor->Cic);
|
||||
monitor_.set_cis(monitor->Cis);
|
||||
monitor_.set_toe(monitor->toe);
|
||||
monitor_.set_toc(monitor->toc);
|
||||
monitor_.set_af0(monitor->af0);
|
||||
monitor_.set_af1(monitor->af1);
|
||||
monitor_.set_af2(monitor->af2);
|
||||
monitor_.set_satclkdrift(monitor->satClkDrift);
|
||||
monitor_.set_dtr(monitor->dtr);
|
||||
monitor_.set_wn(monitor->WN);
|
||||
monitor_.set_tow(monitor->tow);
|
||||
|
||||
// Galileo-specific parameters
|
||||
monitor_.set_iod_ephemeris(monitor->IOD_ephemeris);
|
||||
monitor_.set_iod_nav(monitor->IOD_nav);
|
||||
monitor_.set_sisa(monitor->SISA);
|
||||
monitor_.set_e5a_hs(monitor->E5a_HS);
|
||||
monitor_.set_e5b_hs(monitor->E5b_HS);
|
||||
monitor_.set_e1b_hs(monitor->E1B_HS);
|
||||
monitor_.set_e5a_dvs(monitor->E5a_DVS);
|
||||
monitor_.set_e5b_dvs(monitor->E5b_DVS);
|
||||
monitor_.set_e1b_dvs(monitor->E1B_DVS);
|
||||
monitor_.set_bgd_e1e5a(monitor->BGD_E1E5a);
|
||||
monitor_.set_bgd_e1e5b(monitor->BGD_E1E5b);
|
||||
|
||||
monitor_.SerializeToString(&data);
|
||||
return data;
|
||||
}
|
||||
|
||||
inline Galileo_Ephemeris readProtobuffer(const gnss_sdr::GalileoEphemeris& mon) const //!< Deserialization
|
||||
{
|
||||
Galileo_Ephemeris monitor;
|
||||
|
||||
monitor.PRN = mon.prn();
|
||||
monitor.M_0 = mon.m_0();
|
||||
monitor.delta_n = mon.delta_n();
|
||||
monitor.ecc = mon.ecc();
|
||||
monitor.sqrtA = mon.sqrta();
|
||||
monitor.OMEGA_0 = mon.omega_0();
|
||||
monitor.i_0 = mon.i_0();
|
||||
monitor.omega = mon.omega();
|
||||
monitor.OMEGAdot = mon.omegadot();
|
||||
monitor.idot = mon.idot();
|
||||
monitor.Cuc = mon.cuc();
|
||||
monitor.Cus = mon.cus();
|
||||
monitor.Crc = mon.crc();
|
||||
monitor.Crs = mon.crs();
|
||||
monitor.Cic = mon.cic();
|
||||
monitor.Cis = mon.cis();
|
||||
monitor.toe = mon.toe();
|
||||
monitor.toc = mon.toc();
|
||||
monitor.af0 = mon.af0();
|
||||
monitor.af1 = mon.af1();
|
||||
monitor.af2 = mon.af2();
|
||||
monitor.satClkDrift = mon.satclkdrift();
|
||||
monitor.dtr = mon.dtr();
|
||||
monitor.WN = mon.wn();
|
||||
monitor.tow = mon.tow();
|
||||
|
||||
// Galileo-specific parameters
|
||||
monitor.IOD_ephemeris = mon.iod_ephemeris();
|
||||
monitor.IOD_nav = mon.iod_nav();
|
||||
monitor.SISA = mon.sisa();
|
||||
monitor.E5a_HS = mon.e5a_hs();
|
||||
monitor.E5b_HS = mon.e5b_hs();
|
||||
monitor.E1B_HS = mon.e1b_hs();
|
||||
monitor.E5a_DVS = mon.e5a_dvs();
|
||||
monitor.E5b_DVS = mon.e5b_dvs();
|
||||
monitor.E1B_DVS = mon.e1b_dvs();
|
||||
monitor.BGD_E1E5a = mon.bgd_e1e5a();
|
||||
monitor.BGD_E1E5b = mon.bgd_e1e5b();
|
||||
|
||||
return monitor;
|
||||
}
|
||||
|
||||
private:
|
||||
gnss_sdr::GalileoEphemeris monitor_{};
|
||||
};
|
||||
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GGNSS_SDR_SERDES_GALILEO_EPH_H
|
185
src/algorithms/PVT/libs/serdes_gps_eph.h
Normal file
185
src/algorithms/PVT/libs/serdes_gps_eph.h
Normal file
@ -0,0 +1,185 @@
|
||||
/*!
|
||||
* \file serdes_gps_eph.h
|
||||
* \brief Serialization / Deserialization of Gps_Ephemeris objects using
|
||||
* Protocol Buffers
|
||||
* \author Javier Arribas, 2021. jarribas(at)cttc.es
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_SERDES_GPS_EPH_H
|
||||
#define GNSS_SDR_SERDES_GPS_EPH_H
|
||||
|
||||
#include "gps_ephemeris.h"
|
||||
#include "gps_ephemeris.pb.h" // file created by Protocol Buffers at compile time
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
/** \addtogroup PVT
|
||||
* \{ */
|
||||
/** \addtogroup PVT_libs
|
||||
* \{ */
|
||||
|
||||
/*!
|
||||
* \brief This class implements serialization and deserialization of
|
||||
* Gps_Ephemeris objects using Protocol Buffers.
|
||||
*/
|
||||
class Serdes_Gps_Eph
|
||||
{
|
||||
public:
|
||||
Serdes_Gps_Eph()
|
||||
{
|
||||
// Verify that the version of the library that we linked against is
|
||||
// compatible with the version of the headers we compiled against.
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
}
|
||||
|
||||
~Serdes_Gps_Eph()
|
||||
{
|
||||
// google::protobuf::ShutdownProtobufLibrary();
|
||||
}
|
||||
|
||||
inline Serdes_Gps_Eph(const Serdes_Gps_Eph& other) noexcept //!< Copy constructor
|
||||
{
|
||||
this->monitor_ = other.monitor_;
|
||||
}
|
||||
|
||||
inline Serdes_Gps_Eph& operator=(const Serdes_Gps_Eph& rhs) noexcept //!< Copy assignment operator
|
||||
{
|
||||
this->monitor_ = rhs.monitor_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Serdes_Gps_Eph(Serdes_Gps_Eph&& other) noexcept //!< Move constructor
|
||||
{
|
||||
this->monitor_ = std::move(other.monitor_);
|
||||
}
|
||||
|
||||
inline Serdes_Gps_Eph& operator=(Serdes_Gps_Eph&& other) noexcept //!< Move assignment operator
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
this->monitor_ = std::move(other.monitor_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline std::string createProtobuffer(const std::shared_ptr<Gps_Ephemeris> monitor) //!< Serialization into a string
|
||||
{
|
||||
monitor_.Clear();
|
||||
std::string data;
|
||||
|
||||
monitor_.set_prn(monitor->PRN);
|
||||
monitor_.set_m_0(monitor->M_0);
|
||||
monitor_.set_delta_n(monitor->delta_n);
|
||||
monitor_.set_ecc(monitor->ecc);
|
||||
monitor_.set_sqrta(monitor->sqrtA);
|
||||
monitor_.set_omega_0(monitor->OMEGA_0);
|
||||
monitor_.set_i_0(monitor->i_0);
|
||||
monitor_.set_omega(monitor->omega);
|
||||
monitor_.set_omegadot(monitor->OMEGAdot);
|
||||
monitor_.set_idot(monitor->idot);
|
||||
monitor_.set_cuc(monitor->Cuc);
|
||||
monitor_.set_cus(monitor->Cus);
|
||||
monitor_.set_crc(monitor->Crc);
|
||||
monitor_.set_crs(monitor->Crs);
|
||||
monitor_.set_cic(monitor->Cic);
|
||||
monitor_.set_cis(monitor->Cis);
|
||||
monitor_.set_toe(monitor->toe);
|
||||
monitor_.set_toc(monitor->toc);
|
||||
monitor_.set_af0(monitor->af0);
|
||||
monitor_.set_af1(monitor->af1);
|
||||
monitor_.set_af2(monitor->af2);
|
||||
monitor_.set_satclkdrift(monitor->satClkDrift);
|
||||
monitor_.set_dtr(monitor->dtr);
|
||||
monitor_.set_wn(monitor->WN);
|
||||
monitor_.set_tow(monitor->tow);
|
||||
|
||||
// GPS-specific parameters
|
||||
monitor_.set_code_on_l2(monitor->code_on_L2);
|
||||
monitor_.set_l2_p_data_flag(monitor->L2_P_data_flag);
|
||||
monitor_.set_sv_accuracy(monitor->SV_accuracy);
|
||||
monitor_.set_sv_health(monitor->SV_health);
|
||||
monitor_.set_tgd(monitor->TGD);
|
||||
monitor_.set_iodc(monitor->IODC);
|
||||
monitor_.set_iode_sf2(monitor->IODE_SF2);
|
||||
monitor_.set_iode_sf3(monitor->IODE_SF3);
|
||||
monitor_.set_aodo(monitor->AODO);
|
||||
monitor_.set_fit_interval_flag(monitor->fit_interval_flag);
|
||||
monitor_.set_spare1(monitor->spare1);
|
||||
monitor_.set_spare2(monitor->spare2);
|
||||
monitor_.set_integrity_status_flag(monitor->integrity_status_flag);
|
||||
monitor_.set_alert_flag(monitor->alert_flag);
|
||||
monitor_.set_antispoofing_flag(monitor->antispoofing_flag);
|
||||
|
||||
monitor_.SerializeToString(&data);
|
||||
return data;
|
||||
}
|
||||
|
||||
inline Gps_Ephemeris readProtobuffer(const gnss_sdr::GpsEphemeris& mon) const //!< Deserialization
|
||||
{
|
||||
Gps_Ephemeris monitor;
|
||||
|
||||
monitor.PRN = mon.prn();
|
||||
monitor.M_0 = mon.m_0();
|
||||
monitor.delta_n = mon.delta_n();
|
||||
monitor.ecc = mon.ecc();
|
||||
monitor.sqrtA = mon.sqrta();
|
||||
monitor.OMEGA_0 = mon.omega_0();
|
||||
monitor.i_0 = mon.i_0();
|
||||
monitor.omega = mon.omega();
|
||||
monitor.OMEGAdot = mon.omegadot();
|
||||
monitor.idot = mon.idot();
|
||||
monitor.Cuc = mon.cuc();
|
||||
monitor.Cus = mon.cus();
|
||||
monitor.Crc = mon.crc();
|
||||
monitor.Crs = mon.crs();
|
||||
monitor.Cic = mon.cic();
|
||||
monitor.Cis = mon.cis();
|
||||
monitor.toe = mon.toe();
|
||||
monitor.toc = mon.toc();
|
||||
monitor.af0 = mon.af0();
|
||||
monitor.af1 = mon.af1();
|
||||
monitor.af2 = mon.af2();
|
||||
monitor.satClkDrift = mon.satclkdrift();
|
||||
monitor.dtr = mon.dtr();
|
||||
monitor.WN = mon.wn();
|
||||
monitor.tow = mon.tow();
|
||||
|
||||
// GPS-specific parameters
|
||||
monitor.code_on_L2 = mon.code_on_l2();
|
||||
monitor.L2_P_data_flag = mon.l2_p_data_flag();
|
||||
monitor.SV_accuracy = mon.sv_accuracy();
|
||||
monitor.SV_health = mon.sv_health();
|
||||
monitor.TGD = mon.tgd();
|
||||
monitor.IODC = mon.iodc();
|
||||
monitor.IODE_SF2 = mon.iode_sf2();
|
||||
monitor.IODE_SF3 = mon.iode_sf3();
|
||||
monitor.AODO = mon.aodo();
|
||||
monitor.fit_interval_flag = mon.fit_interval_flag();
|
||||
monitor.spare1 = mon.spare1();
|
||||
monitor.spare2 = mon.spare2();
|
||||
monitor.integrity_status_flag = mon.integrity_status_flag();
|
||||
monitor.alert_flag = mon.alert_flag();
|
||||
monitor.antispoofing_flag = mon.antispoofing_flag();
|
||||
|
||||
return monitor;
|
||||
}
|
||||
|
||||
private:
|
||||
gnss_sdr::GpsEphemeris monitor_{};
|
||||
};
|
||||
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GNSS_SDR_SERDES_GPS_EPH_H
|
@ -162,13 +162,13 @@ void pcps_assisted_acquisition_cc::get_assistance()
|
||||
// TODO: use the LO tolerance here
|
||||
if (gps_acq_assisistance.dopplerUncertainty >= 1000)
|
||||
{
|
||||
d_doppler_max = gps_acq_assisistance.d_Doppler0 + gps_acq_assisistance.dopplerUncertainty * 2;
|
||||
d_doppler_min = gps_acq_assisistance.d_Doppler0 - gps_acq_assisistance.dopplerUncertainty * 2;
|
||||
d_doppler_max = gps_acq_assisistance.Doppler0 + gps_acq_assisistance.dopplerUncertainty * 2;
|
||||
d_doppler_min = gps_acq_assisistance.Doppler0 - gps_acq_assisistance.dopplerUncertainty * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_doppler_max = gps_acq_assisistance.d_Doppler0 + 1000;
|
||||
d_doppler_min = gps_acq_assisistance.d_Doppler0 - 1000;
|
||||
d_doppler_max = gps_acq_assisistance.Doppler0 + 1000;
|
||||
d_doppler_min = gps_acq_assisistance.Doppler0 - 1000;
|
||||
}
|
||||
this->d_disable_assist = false;
|
||||
std::cout << "Acq assist ENABLED for GPS SV " << this->d_gnss_synchro->PRN << " (Doppler max,Doppler min)=("
|
||||
|
@ -44,10 +44,9 @@ Acq_Conf::Acq_Conf()
|
||||
dump = false;
|
||||
blocking = true;
|
||||
make_2_steps = false;
|
||||
dump_filename = "";
|
||||
dump_channel = 0U;
|
||||
it_size = sizeof(gr_complex);
|
||||
item_type = "gr_complex";
|
||||
item_type = std::string("gr_complex");
|
||||
blocking_on_standby = false;
|
||||
use_automatic_resampler = false;
|
||||
resampler_ratio = 1.0;
|
||||
|
@ -179,25 +179,25 @@ gr::basic_block_sptr Channel::get_left_block_trk()
|
||||
return trk_->get_left_block();
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr Channel::get_right_block_trk()
|
||||
{
|
||||
return trk_->get_right_block();
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr Channel::get_left_block_acq()
|
||||
{
|
||||
if (flag_enable_fpga_)
|
||||
{
|
||||
LOG(ERROR) << "Enabled FPGA and called get_left_block() in channel interface";
|
||||
}
|
||||
return acq_->get_left_block();
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr Channel::get_right_block_acq()
|
||||
{
|
||||
return acq_->get_right_block();
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr Channel::get_right_block()
|
||||
{
|
||||
return nav_->get_right_block();
|
||||
|
@ -32,6 +32,7 @@ set(GNSS_SPLIBS_SOURCES
|
||||
trackingcmd.cc
|
||||
pass_through.cc
|
||||
short_x2_to_cshort.cc
|
||||
gnss_sdr_string_literals.cc
|
||||
)
|
||||
|
||||
set(GNSS_SPLIBS_HEADERS
|
||||
@ -63,6 +64,7 @@ set(GNSS_SPLIBS_HEADERS
|
||||
trackingcmd.h
|
||||
pass_through.h
|
||||
short_x2_to_cshort.h
|
||||
gnss_sdr_string_literals.h
|
||||
)
|
||||
|
||||
if(ENABLE_OPENCL)
|
||||
|
42
src/algorithms/libs/gnss_sdr_string_literals.cc
Normal file
42
src/algorithms/libs/gnss_sdr_string_literals.cc
Normal file
@ -0,0 +1,42 @@
|
||||
/*!
|
||||
* \file gnss_sdr_string_literals.cc
|
||||
* \brief This file implements the ""s operator for std::string in C++11, and
|
||||
* puts it into the std::string_literals namespace. This is already implemented
|
||||
* in C++14, so this is only compiled when using C++11. The .cc file is required
|
||||
* for avoiding the duplication of symbols.
|
||||
*
|
||||
* \author Carles Fernandez-Prades, 2021. cfernandez(at)cttc.es
|
||||
*
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
|
||||
#if __cplusplus == 201103L
|
||||
|
||||
namespace std
|
||||
{
|
||||
namespace string_literals
|
||||
{
|
||||
std::string operator"" s(const char* str, std::size_t len)
|
||||
{
|
||||
return std::string(str, len);
|
||||
};
|
||||
} // namespace string_literals
|
||||
} // namespace std
|
||||
|
||||
#else
|
||||
// Avoid "gnss_sdr_string_literals.cc.o has no symbols" warning in MacOS with a
|
||||
// dummy symbol so ranlib does not complain
|
||||
void avoid_no_symbols_warning() {}
|
||||
|
||||
#endif // __cplusplus == 201103L
|
48
src/algorithms/libs/gnss_sdr_string_literals.h
Normal file
48
src/algorithms/libs/gnss_sdr_string_literals.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*!
|
||||
* \file gnss_sdr_string_literals.h
|
||||
* \brief This file implements the ""s operator for std::string in C++11, and
|
||||
* puts it into the std::string_literals namespace. This is already implemented
|
||||
* in C++14, so this is only compiled when using C++11. The .cc file is required
|
||||
* for avoiding the duplication of symbols.
|
||||
*
|
||||
* \author Carles Fernandez-Prades, 2021. cfernandez(at)cttc.es
|
||||
*
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_STRING_LITERALS_H
|
||||
#define GNSS_SDR_STRING_LITERALS_H
|
||||
|
||||
/** \addtogroup Algorithms_Library
|
||||
* \{ */
|
||||
/** \addtogroup Algorithm_libs algorithms_libs
|
||||
* \{ */
|
||||
|
||||
#if __cplusplus == 201103L
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
namespace std
|
||||
{
|
||||
namespace string_literals
|
||||
{
|
||||
std::string operator"" s(const char* str, std::size_t len);
|
||||
} // namespace string_literals
|
||||
} // namespace std
|
||||
|
||||
#endif // __cplusplus == 201103L
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
|
||||
#endif // GNSS_SDR_STRING_LITERALS_H
|
@ -186,18 +186,15 @@ const int MAXPRNGAL = 36; //!< max satellite PRN numbe
|
||||
const int NSATGAL = (MAXPRNGAL - MINPRNGAL + 1); //!< number of Galileo satellites
|
||||
const int NSYSGAL = 1;
|
||||
|
||||
const int MAXPRNQZS = 199; //!< max satellite PRN number of QZSS
|
||||
const int MINPRNQZS = 193; //!< min satellite PRN number of QZSS
|
||||
#ifdef ENAQZS
|
||||
const int MINPRNQZS = 193; //!< min satellite PRN number of QZSS
|
||||
const int MAXPRNQZS = 199; //!< max satellite PRN number of QZSS
|
||||
const int MINPRNQZS_S = 183; //!< min satellite PRN number of QZSS SAIF
|
||||
const int MAXPRNQZS_S = 189; //!< max satellite PRN number of QZSS SAIF
|
||||
const int NSATQZS = (MAXPRNQZS - MINPRNQZS + 1); //!< number of QZSS satellites
|
||||
const int NSYSQZS = 1;
|
||||
#else
|
||||
const int MINPRNQZS = 0;
|
||||
const int MAXPRNQZS = 0;
|
||||
const int MINPRNQZS_S = 0;
|
||||
const int MAXPRNQZS_S = 0;
|
||||
const int NSATQZS = 0;
|
||||
const int NSYSQZS = 0;
|
||||
#endif
|
||||
@ -215,26 +212,22 @@ const int NSATBDS = 0;
|
||||
const int NSYSBDS = 0;
|
||||
#endif
|
||||
|
||||
const int MINPRNIRN = 1; //!< min satellite sat number of IRNSS
|
||||
const int MAXPRNIRN = 7; //!< max satellite sat number of IRNSS
|
||||
#ifdef ENAIRN
|
||||
const int MINPRNIRN = 1; //!< min satellite sat number of IRNSS
|
||||
const int MAXPRNIRN = 7; //!< max satellite sat number of IRNSS
|
||||
const int NSATIRN = (MAXPRNIRN - MINPRNIRN + 1); //!< number of IRNSS satellites
|
||||
const int NSYSIRN = 1;
|
||||
#else
|
||||
const int MINPRNIRN = 0;
|
||||
const int MAXPRNIRN = 0;
|
||||
const int NSATIRN = 0;
|
||||
const int NSYSIRN = 0;
|
||||
#endif
|
||||
|
||||
const int MINPRNLEO = 1; //!< min satellite sat number of LEO
|
||||
const int MAXPRNLEO = 10; //!< max satellite sat number of LEO */
|
||||
#ifdef ENALEO
|
||||
const int MINPRNLEO = 1; //!< min satellite sat number of LEO
|
||||
const int NSATLEO = 10; //!< max satellite sat number of LEO
|
||||
const int NSATLEO = (MAXPRNLEO - MINPRNLEO + 1); //!< number of LEO satellites
|
||||
const int NSYSLEO = 1;
|
||||
#else
|
||||
const int MINPRNLEO = 0;
|
||||
const int MAXPRNLEO = 0;
|
||||
const int NSATLEO = 0;
|
||||
const int NSYSLEO = 0;
|
||||
#endif
|
||||
|
@ -168,36 +168,36 @@ 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};
|
||||
// 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;
|
||||
rtklib_sat.M0 = gal_eph.M0_1;
|
||||
rtklib_sat.deln = gal_eph.delta_n_3;
|
||||
rtklib_sat.OMG0 = gal_eph.OMEGA_0_2;
|
||||
rtklib_sat.OMGd = gal_eph.OMEGA_dot_3;
|
||||
rtklib_sat.omg = gal_eph.omega_2;
|
||||
rtklib_sat.i0 = gal_eph.i_0_2;
|
||||
rtklib_sat.idot = gal_eph.iDot_2;
|
||||
rtklib_sat.e = gal_eph.e_1;
|
||||
rtklib_sat.sat = gal_eph.PRN + NSATGPS + NSATGLO;
|
||||
rtklib_sat.A = gal_eph.sqrtA * gal_eph.sqrtA;
|
||||
rtklib_sat.M0 = gal_eph.M_0;
|
||||
rtklib_sat.deln = gal_eph.delta_n;
|
||||
rtklib_sat.OMG0 = gal_eph.OMEGA_0;
|
||||
rtklib_sat.OMGd = gal_eph.OMEGAdot;
|
||||
rtklib_sat.omg = gal_eph.omega;
|
||||
rtklib_sat.i0 = gal_eph.i_0;
|
||||
rtklib_sat.idot = gal_eph.idot;
|
||||
rtklib_sat.e = gal_eph.ecc;
|
||||
rtklib_sat.Adot = 0; // only in CNAV;
|
||||
rtklib_sat.ndot = 0; // only in CNAV;
|
||||
|
||||
rtklib_sat.week = gal_eph.WN_5 + 1024; /* week of tow in GPS (not mod-1024) week scale */
|
||||
rtklib_sat.cic = gal_eph.C_ic_4;
|
||||
rtklib_sat.cis = gal_eph.C_is_4;
|
||||
rtklib_sat.cuc = gal_eph.C_uc_3;
|
||||
rtklib_sat.cus = gal_eph.C_us_3;
|
||||
rtklib_sat.crc = gal_eph.C_rc_3;
|
||||
rtklib_sat.crs = gal_eph.C_rs_3;
|
||||
rtklib_sat.f0 = gal_eph.af0_4;
|
||||
rtklib_sat.f1 = gal_eph.af1_4;
|
||||
rtklib_sat.f2 = gal_eph.af2_4;
|
||||
rtklib_sat.tgd[0] = gal_eph.BGD_E1E5a_5;
|
||||
rtklib_sat.tgd[1] = gal_eph.BGD_E1E5b_5;
|
||||
rtklib_sat.week = gal_eph.WN + 1024; /* week of tow in GPS (not mod-1024) week scale */
|
||||
rtklib_sat.cic = gal_eph.Cic;
|
||||
rtklib_sat.cis = gal_eph.Cis;
|
||||
rtklib_sat.cuc = gal_eph.Cuc;
|
||||
rtklib_sat.cus = gal_eph.Cus;
|
||||
rtklib_sat.crc = gal_eph.Crc;
|
||||
rtklib_sat.crs = gal_eph.Crs;
|
||||
rtklib_sat.f0 = gal_eph.af0;
|
||||
rtklib_sat.f1 = gal_eph.af1;
|
||||
rtklib_sat.f2 = gal_eph.af2;
|
||||
rtklib_sat.tgd[0] = gal_eph.BGD_E1E5a;
|
||||
rtklib_sat.tgd[1] = gal_eph.BGD_E1E5b;
|
||||
rtklib_sat.tgd[2] = 0;
|
||||
rtklib_sat.tgd[3] = 0;
|
||||
rtklib_sat.toes = gal_eph.t0e_1;
|
||||
rtklib_sat.toc = gpst2time(rtklib_sat.week, gal_eph.t0c_4);
|
||||
rtklib_sat.ttr = gpst2time(rtklib_sat.week, gal_eph.TOW_5);
|
||||
rtklib_sat.toes = gal_eph.toe;
|
||||
rtklib_sat.toc = gpst2time(rtklib_sat.week, gal_eph.toc);
|
||||
rtklib_sat.ttr = gpst2time(rtklib_sat.week, gal_eph.tow);
|
||||
|
||||
/* adjustment for week handover */
|
||||
double tow;
|
||||
@ -226,36 +226,36 @@ eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph, bool pre_2009_file)
|
||||
{
|
||||
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};
|
||||
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;
|
||||
rtklib_sat.deln = gps_eph.d_Delta_n;
|
||||
rtklib_sat.OMG0 = gps_eph.d_OMEGA0;
|
||||
rtklib_sat.OMGd = gps_eph.d_OMEGA_DOT;
|
||||
rtklib_sat.omg = gps_eph.d_OMEGA;
|
||||
rtklib_sat.i0 = gps_eph.d_i_0;
|
||||
rtklib_sat.idot = gps_eph.d_IDOT;
|
||||
rtklib_sat.e = gps_eph.d_e_eccentricity;
|
||||
rtklib_sat.sat = gps_eph.PRN;
|
||||
rtklib_sat.A = gps_eph.sqrtA * gps_eph.sqrtA;
|
||||
rtklib_sat.M0 = gps_eph.M_0;
|
||||
rtklib_sat.deln = gps_eph.delta_n;
|
||||
rtklib_sat.OMG0 = gps_eph.OMEGA_0;
|
||||
rtklib_sat.OMGd = gps_eph.OMEGAdot;
|
||||
rtklib_sat.omg = gps_eph.omega;
|
||||
rtklib_sat.i0 = gps_eph.i_0;
|
||||
rtklib_sat.idot = gps_eph.idot;
|
||||
rtklib_sat.e = gps_eph.ecc;
|
||||
rtklib_sat.Adot = 0; // only in CNAV;
|
||||
rtklib_sat.ndot = 0; // only in CNAV;
|
||||
|
||||
rtklib_sat.week = adjgpsweek(gps_eph.i_GPS_week, pre_2009_file); /* week of tow */
|
||||
rtklib_sat.cic = gps_eph.d_Cic;
|
||||
rtklib_sat.cis = gps_eph.d_Cis;
|
||||
rtklib_sat.cuc = gps_eph.d_Cuc;
|
||||
rtklib_sat.cus = gps_eph.d_Cus;
|
||||
rtklib_sat.crc = gps_eph.d_Crc;
|
||||
rtklib_sat.crs = gps_eph.d_Crs;
|
||||
rtklib_sat.f0 = gps_eph.d_A_f0;
|
||||
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.week = adjgpsweek(gps_eph.WN, pre_2009_file); /* week of tow */
|
||||
rtklib_sat.cic = gps_eph.Cic;
|
||||
rtklib_sat.cis = gps_eph.Cis;
|
||||
rtklib_sat.cuc = gps_eph.Cuc;
|
||||
rtklib_sat.cus = gps_eph.Cus;
|
||||
rtklib_sat.crc = gps_eph.Crc;
|
||||
rtklib_sat.crs = gps_eph.Crs;
|
||||
rtklib_sat.f0 = gps_eph.af0;
|
||||
rtklib_sat.f1 = gps_eph.af1;
|
||||
rtklib_sat.f2 = gps_eph.af2;
|
||||
rtklib_sat.tgd[0] = gps_eph.TGD;
|
||||
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);
|
||||
rtklib_sat.toes = gps_eph.toe;
|
||||
rtklib_sat.toc = gpst2time(rtklib_sat.week, gps_eph.toc);
|
||||
rtklib_sat.ttr = gpst2time(rtklib_sat.week, gps_eph.tow);
|
||||
|
||||
/* adjustment for week handover */
|
||||
double tow;
|
||||
@ -284,45 +284,45 @@ eph_t eph_to_rtklib(const Beidou_Dnav_Ephemeris& bei_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};
|
||||
rtklib_sat.sat = bei_eph.i_satellite_PRN + NSATGPS + NSATGLO + NSATGAL + NSATQZS;
|
||||
rtklib_sat.A = bei_eph.d_sqrt_A * bei_eph.d_sqrt_A;
|
||||
rtklib_sat.M0 = bei_eph.d_M_0;
|
||||
rtklib_sat.deln = bei_eph.d_Delta_n;
|
||||
rtklib_sat.OMG0 = bei_eph.d_OMEGA0;
|
||||
rtklib_sat.OMGd = bei_eph.d_OMEGA_DOT;
|
||||
rtklib_sat.omg = bei_eph.d_OMEGA;
|
||||
rtklib_sat.i0 = bei_eph.d_i_0;
|
||||
rtklib_sat.idot = bei_eph.d_IDOT;
|
||||
rtklib_sat.e = bei_eph.d_eccentricity;
|
||||
rtklib_sat.sat = bei_eph.PRN + NSATGPS + NSATGLO + NSATGAL + NSATQZS;
|
||||
rtklib_sat.A = bei_eph.sqrtA * bei_eph.sqrtA;
|
||||
rtklib_sat.M0 = bei_eph.M_0;
|
||||
rtklib_sat.deln = bei_eph.delta_n;
|
||||
rtklib_sat.OMG0 = bei_eph.OMEGA_0;
|
||||
rtklib_sat.OMGd = bei_eph.OMEGAdot;
|
||||
rtklib_sat.omg = bei_eph.omega;
|
||||
rtklib_sat.i0 = bei_eph.i_0;
|
||||
rtklib_sat.idot = bei_eph.idot;
|
||||
rtklib_sat.e = bei_eph.ecc;
|
||||
rtklib_sat.Adot = 0; // only in CNAV;
|
||||
rtklib_sat.ndot = 0; // only in CNAV;
|
||||
|
||||
rtklib_sat.svh = bei_eph.i_SV_health;
|
||||
rtklib_sat.sva = bei_eph.i_SV_accuracy;
|
||||
rtklib_sat.svh = bei_eph.SV_health;
|
||||
rtklib_sat.sva = bei_eph.SV_accuracy;
|
||||
|
||||
rtklib_sat.code = bei_eph.i_sig_type; /* B1I data */
|
||||
rtklib_sat.flag = bei_eph.i_nav_type; /* MEO/IGSO satellite */
|
||||
rtklib_sat.iode = static_cast<int32_t>(bei_eph.d_AODE); /* AODE */
|
||||
rtklib_sat.iodc = static_cast<int32_t>(bei_eph.d_AODC); /* AODC */
|
||||
rtklib_sat.code = bei_eph.sig_type; /* B1I data */
|
||||
rtklib_sat.flag = bei_eph.nav_type; /* MEO/IGSO satellite */
|
||||
rtklib_sat.iode = static_cast<int32_t>(bei_eph.AODE); /* AODE */
|
||||
rtklib_sat.iodc = static_cast<int32_t>(bei_eph.AODC); /* AODC */
|
||||
|
||||
rtklib_sat.week = bei_eph.i_BEIDOU_week; /* week of tow */
|
||||
rtklib_sat.cic = bei_eph.d_Cic;
|
||||
rtklib_sat.cis = bei_eph.d_Cis;
|
||||
rtklib_sat.cuc = bei_eph.d_Cuc;
|
||||
rtklib_sat.cus = bei_eph.d_Cus;
|
||||
rtklib_sat.crc = bei_eph.d_Crc;
|
||||
rtklib_sat.crs = bei_eph.d_Crs;
|
||||
rtklib_sat.f0 = bei_eph.d_A_f0;
|
||||
rtklib_sat.f1 = bei_eph.d_A_f1;
|
||||
rtklib_sat.f2 = bei_eph.d_A_f2;
|
||||
rtklib_sat.tgd[0] = bei_eph.d_TGD1;
|
||||
rtklib_sat.tgd[1] = bei_eph.d_TGD2;
|
||||
rtklib_sat.week = bei_eph.WN; /* week of tow */
|
||||
rtklib_sat.cic = bei_eph.Cic;
|
||||
rtklib_sat.cis = bei_eph.Cis;
|
||||
rtklib_sat.cuc = bei_eph.Cuc;
|
||||
rtklib_sat.cus = bei_eph.Cus;
|
||||
rtklib_sat.crc = bei_eph.Crc;
|
||||
rtklib_sat.crs = bei_eph.Crs;
|
||||
rtklib_sat.f0 = bei_eph.af0;
|
||||
rtklib_sat.f1 = bei_eph.af1;
|
||||
rtklib_sat.f2 = bei_eph.af2;
|
||||
rtklib_sat.tgd[0] = bei_eph.TGD1;
|
||||
rtklib_sat.tgd[1] = bei_eph.TGD2;
|
||||
rtklib_sat.tgd[2] = 0.0;
|
||||
rtklib_sat.tgd[3] = 0.0;
|
||||
rtklib_sat.toes = bei_eph.d_Toe;
|
||||
rtklib_sat.toe = bdt2gpst(bdt2time(rtklib_sat.week, bei_eph.d_Toe));
|
||||
rtklib_sat.toc = bdt2gpst(bdt2time(rtklib_sat.week, bei_eph.d_Toc));
|
||||
rtklib_sat.ttr = bdt2gpst(bdt2time(rtklib_sat.week, bei_eph.d_TOW));
|
||||
rtklib_sat.toes = bei_eph.toe;
|
||||
rtklib_sat.toe = bdt2gpst(bdt2time(rtklib_sat.week, bei_eph.toe));
|
||||
rtklib_sat.toc = bdt2gpst(bdt2time(rtklib_sat.week, bei_eph.toc));
|
||||
rtklib_sat.ttr = bdt2gpst(bdt2time(rtklib_sat.week, bei_eph.tow));
|
||||
/* adjustment for week handover */
|
||||
double tow;
|
||||
double toc;
|
||||
@ -353,44 +353,40 @@ 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};
|
||||
rtklib_sat.sat = gps_cnav_eph.i_satellite_PRN;
|
||||
const double A_REF = 26559710.0; // See IS-GPS-200L, pp. 161
|
||||
rtklib_sat.A = A_REF + gps_cnav_eph.d_DELTA_A;
|
||||
rtklib_sat.M0 = gps_cnav_eph.d_M_0;
|
||||
rtklib_sat.deln = gps_cnav_eph.d_Delta_n;
|
||||
rtklib_sat.OMG0 = gps_cnav_eph.d_OMEGA0;
|
||||
// Compute the angle between the ascending node and the Greenwich meridian
|
||||
const double OMEGA_DOT_REF = -2.6e-9; // semicircles / s, see IS-GPS-200L pp. 160
|
||||
double d_OMEGA_DOT = OMEGA_DOT_REF * GNSS_PI + gps_cnav_eph.d_DELTA_OMEGA_DOT;
|
||||
rtklib_sat.OMGd = d_OMEGA_DOT;
|
||||
rtklib_sat.omg = gps_cnav_eph.d_OMEGA;
|
||||
rtklib_sat.i0 = gps_cnav_eph.d_i_0;
|
||||
rtklib_sat.idot = gps_cnav_eph.d_IDOT;
|
||||
rtklib_sat.e = gps_cnav_eph.d_e_eccentricity;
|
||||
rtklib_sat.Adot = gps_cnav_eph.d_A_DOT; // only in CNAV;
|
||||
rtklib_sat.ndot = gps_cnav_eph.d_DELTA_DOT_N; // only in CNAV;
|
||||
rtklib_sat.sat = gps_cnav_eph.PRN;
|
||||
rtklib_sat.A = gps_cnav_eph.sqrtA * gps_cnav_eph.sqrtA;
|
||||
rtklib_sat.M0 = gps_cnav_eph.M_0;
|
||||
rtklib_sat.deln = gps_cnav_eph.delta_n;
|
||||
rtklib_sat.OMG0 = gps_cnav_eph.OMEGA_0;
|
||||
rtklib_sat.OMGd = gps_cnav_eph.OMEGAdot;
|
||||
rtklib_sat.omg = gps_cnav_eph.omega;
|
||||
rtklib_sat.i0 = gps_cnav_eph.i_0;
|
||||
rtklib_sat.idot = gps_cnav_eph.idot;
|
||||
rtklib_sat.e = gps_cnav_eph.ecc;
|
||||
rtklib_sat.Adot = gps_cnav_eph.Adot; // only in CNAV;
|
||||
rtklib_sat.ndot = gps_cnav_eph.delta_ndot; // only in CNAV;
|
||||
|
||||
rtklib_sat.week = adjgpsweek(gps_cnav_eph.i_GPS_week); /* week of tow */
|
||||
rtklib_sat.cic = gps_cnav_eph.d_Cic;
|
||||
rtklib_sat.cis = gps_cnav_eph.d_Cis;
|
||||
rtklib_sat.cuc = gps_cnav_eph.d_Cuc;
|
||||
rtklib_sat.cus = gps_cnav_eph.d_Cus;
|
||||
rtklib_sat.crc = gps_cnav_eph.d_Crc;
|
||||
rtklib_sat.crs = gps_cnav_eph.d_Crs;
|
||||
rtklib_sat.f0 = gps_cnav_eph.d_A_f0;
|
||||
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.week = adjgpsweek(gps_cnav_eph.WN); /* week of tow */
|
||||
rtklib_sat.cic = gps_cnav_eph.Cic;
|
||||
rtklib_sat.cis = gps_cnav_eph.Cis;
|
||||
rtklib_sat.cuc = gps_cnav_eph.Cuc;
|
||||
rtklib_sat.cus = gps_cnav_eph.Cus;
|
||||
rtklib_sat.crc = gps_cnav_eph.Crc;
|
||||
rtklib_sat.crs = gps_cnav_eph.Crs;
|
||||
rtklib_sat.f0 = gps_cnav_eph.af0;
|
||||
rtklib_sat.f1 = gps_cnav_eph.af1;
|
||||
rtklib_sat.f2 = gps_cnav_eph.af2;
|
||||
rtklib_sat.tgd[0] = gps_cnav_eph.TGD;
|
||||
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);
|
||||
rtklib_sat.isc[0] = gps_cnav_eph.ISCL1;
|
||||
rtklib_sat.isc[1] = gps_cnav_eph.ISCL2;
|
||||
rtklib_sat.isc[2] = gps_cnav_eph.ISCL5I;
|
||||
rtklib_sat.isc[3] = gps_cnav_eph.ISCL5Q;
|
||||
rtklib_sat.toes = gps_cnav_eph.toe1;
|
||||
rtklib_sat.toc = gpst2time(rtklib_sat.week, gps_cnav_eph.toc);
|
||||
rtklib_sat.ttr = gpst2time(rtklib_sat.week, gps_cnav_eph.tow);
|
||||
|
||||
/* adjustment for week handover */
|
||||
double tow;
|
||||
@ -421,24 +417,24 @@ alm_t alm_to_rtklib(const Gps_Almanac& gps_alm)
|
||||
|
||||
rtklib_alm = {0, 0, 0, 0, {0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
rtklib_alm.sat = gps_alm.i_satellite_PRN;
|
||||
rtklib_alm.svh = gps_alm.i_SV_health;
|
||||
rtklib_alm.svconf = gps_alm.i_AS_status;
|
||||
rtklib_alm.week = gps_alm.i_WNa;
|
||||
rtklib_alm.sat = gps_alm.PRN;
|
||||
rtklib_alm.svh = gps_alm.SV_health;
|
||||
rtklib_alm.svconf = gps_alm.AS_status;
|
||||
rtklib_alm.week = gps_alm.WNa;
|
||||
gtime_t toa;
|
||||
toa.time = gps_alm.i_Toa;
|
||||
toa.time = gps_alm.toa;
|
||||
toa.sec = 0.0;
|
||||
rtklib_alm.toa = toa;
|
||||
rtklib_alm.A = gps_alm.d_sqrt_A * gps_alm.d_sqrt_A;
|
||||
rtklib_alm.e = gps_alm.d_e_eccentricity;
|
||||
rtklib_alm.i0 = (gps_alm.d_Delta_i + 0.3) * GNSS_PI;
|
||||
rtklib_alm.OMG0 = gps_alm.d_OMEGA0 * GNSS_PI;
|
||||
rtklib_alm.OMGd = gps_alm.d_OMEGA_DOT * GNSS_PI;
|
||||
rtklib_alm.omg = gps_alm.d_OMEGA * GNSS_PI;
|
||||
rtklib_alm.M0 = gps_alm.d_M_0 * GNSS_PI;
|
||||
rtklib_alm.f0 = gps_alm.d_A_f0;
|
||||
rtklib_alm.f1 = gps_alm.d_A_f1;
|
||||
rtklib_alm.toas = gps_alm.i_Toa;
|
||||
rtklib_alm.A = gps_alm.sqrtA * gps_alm.sqrtA;
|
||||
rtklib_alm.e = gps_alm.ecc;
|
||||
rtklib_alm.i0 = (gps_alm.delta_i + 0.3) * GNSS_PI;
|
||||
rtklib_alm.OMG0 = gps_alm.OMEGA_0 * GNSS_PI;
|
||||
rtklib_alm.OMGd = gps_alm.OMEGAdot * GNSS_PI;
|
||||
rtklib_alm.omg = gps_alm.omega * GNSS_PI;
|
||||
rtklib_alm.M0 = gps_alm.M_0 * GNSS_PI;
|
||||
rtklib_alm.f0 = gps_alm.af0;
|
||||
rtklib_alm.f1 = gps_alm.af1;
|
||||
rtklib_alm.toas = gps_alm.toa;
|
||||
|
||||
return rtklib_alm;
|
||||
}
|
||||
@ -450,25 +446,25 @@ alm_t alm_to_rtklib(const Galileo_Almanac& gal_alm)
|
||||
|
||||
rtklib_alm = {0, 0, 0, 0, {0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
rtklib_alm.sat = gal_alm.i_satellite_PRN + NSATGPS + NSATGLO;
|
||||
rtklib_alm.sat = gal_alm.PRN + NSATGPS + NSATGLO;
|
||||
rtklib_alm.svh = gal_alm.E1B_HS;
|
||||
rtklib_alm.svconf = gal_alm.E1B_HS;
|
||||
rtklib_alm.week = gal_alm.i_WNa;
|
||||
rtklib_alm.week = gal_alm.WNa;
|
||||
gtime_t toa;
|
||||
toa.time = gal_alm.i_Toa;
|
||||
toa.time = gal_alm.toa;
|
||||
toa.sec = 0.0;
|
||||
rtklib_alm.toa = toa;
|
||||
rtklib_alm.A = 5440.588203494 + gal_alm.d_Delta_sqrt_A;
|
||||
rtklib_alm.A = 5440.588203494 + gal_alm.delta_sqrtA;
|
||||
rtklib_alm.A = rtklib_alm.A * rtklib_alm.A;
|
||||
rtklib_alm.e = gal_alm.d_e_eccentricity;
|
||||
rtklib_alm.i0 = (gal_alm.d_Delta_i + 56.0 / 180.0) * GNSS_PI;
|
||||
rtklib_alm.OMG0 = gal_alm.d_OMEGA0 * GNSS_PI;
|
||||
rtklib_alm.OMGd = gal_alm.d_OMEGA_DOT * GNSS_PI;
|
||||
rtklib_alm.omg = gal_alm.d_OMEGA * GNSS_PI;
|
||||
rtklib_alm.M0 = gal_alm.d_M_0 * GNSS_PI;
|
||||
rtklib_alm.f0 = gal_alm.d_A_f0;
|
||||
rtklib_alm.f1 = gal_alm.d_A_f1;
|
||||
rtklib_alm.toas = gal_alm.i_Toa;
|
||||
rtklib_alm.e = gal_alm.ecc;
|
||||
rtklib_alm.i0 = (gal_alm.delta_i + 56.0 / 180.0) * GNSS_PI;
|
||||
rtklib_alm.OMG0 = gal_alm.OMEGA_0 * GNSS_PI;
|
||||
rtklib_alm.OMGd = gal_alm.OMEGAdot * GNSS_PI;
|
||||
rtklib_alm.omg = gal_alm.omega * GNSS_PI;
|
||||
rtklib_alm.M0 = gal_alm.M_0 * GNSS_PI;
|
||||
rtklib_alm.f0 = gal_alm.af0;
|
||||
rtklib_alm.f1 = gal_alm.af1;
|
||||
rtklib_alm.toas = gal_alm.toa;
|
||||
|
||||
return rtklib_alm;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "rtklib_rtkcmn.h"
|
||||
#include <glog/logging.h>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <dirent.h>
|
||||
#include <iostream>
|
||||
@ -273,19 +274,19 @@ int satno(int sys, int prn)
|
||||
}
|
||||
return NSATGPS + NSATGLO + NSATGAL + prn - MINPRNQZS + 1;
|
||||
case SYS_BDS:
|
||||
if (prn < MINPRNBDS || MAXPRNBDS < prn)
|
||||
if (MAXPRNBDS < prn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return NSATGPS + NSATGLO + NSATGAL + NSATQZS + prn - MINPRNBDS + 1;
|
||||
case SYS_IRN:
|
||||
if (prn < MINPRNIRN || MAXPRNIRN < prn)
|
||||
if (MAXPRNIRN < prn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return NSATGPS + NSATGLO + NSATGAL + NSATQZS + NSATBDS + prn - MINPRNIRN + 1;
|
||||
case SYS_LEO:
|
||||
if (prn < MINPRNLEO || MAXPRNLEO < prn)
|
||||
if (MAXPRNLEO < prn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -442,6 +443,11 @@ int satid2no(const char *id)
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (prn <= 0 || prn > MAXSAT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return satno(sys, prn);
|
||||
}
|
||||
|
||||
@ -1417,6 +1423,7 @@ void matfprint(const double A[], int n, int m, int p, int q, FILE *fp)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void matsprint(const double A[], int n, int m, int p, int q, std::string &buffer)
|
||||
{
|
||||
int i;
|
||||
@ -2689,6 +2696,20 @@ void addpcv(const pcv_t *pcv, pcvs_t *pcvs)
|
||||
}
|
||||
|
||||
|
||||
/* strncpy without truncation ------------------------------------------------*/
|
||||
char *strncpy_no_trunc(char *out, size_t outsz, const char *in, size_t insz)
|
||||
{
|
||||
assert(outsz > 0);
|
||||
while (--outsz > 0 && insz > 0 && *in)
|
||||
{
|
||||
*out++ = *in++;
|
||||
insz--;
|
||||
}
|
||||
*out = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/* read ngs antenna parameter file -------------------------------------------*/
|
||||
int readngspcv(const char *file, pcvs_t *pcvs)
|
||||
{
|
||||
@ -2718,7 +2739,7 @@ int readngspcv(const char *file, pcvs_t *pcvs)
|
||||
if (++n == 1)
|
||||
{
|
||||
pcv = pcv0;
|
||||
strncpy(pcv.type, buff, 61);
|
||||
strncpy_no_trunc(pcv.type, 61, buff, 256);
|
||||
pcv.type[61] = '\0';
|
||||
}
|
||||
else if (n == 2)
|
||||
|
@ -59,6 +59,7 @@
|
||||
#define GNSS_SDR_RTKLIB_RTKCMN_H
|
||||
|
||||
#include "rtklib.h"
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
|
||||
@ -96,7 +97,7 @@
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
char *strncpy_no_trunc(char *out, size_t outsz, const char *in, size_t insz);
|
||||
void fatalerr(const char *format, ...);
|
||||
int satno(int sys, int prn);
|
||||
int satsys(int sat, int *prn);
|
||||
|
@ -232,7 +232,7 @@ void read_results(std::vector<volk_gnsssdr_test_results_t> *results, std::string
|
||||
|
||||
if (single_kernel_result.size() == 3)
|
||||
{
|
||||
volk_gnsssdr_test_results_t kernel_result;
|
||||
volk_gnsssdr_test_results_t kernel_result{};
|
||||
kernel_result.name = std::string(single_kernel_result[0]);
|
||||
kernel_result.config_name = std::string(single_kernel_result[0]);
|
||||
kernel_result.best_arch_u = std::string(single_kernel_result[1]);
|
||||
|
@ -119,8 +119,11 @@ if(FILESYSTEM_FIND_QUIETLY)
|
||||
set(CMAKE_REQUIRED_QUIET ${FILESYSTEM_FIND_QUIETLY})
|
||||
endif()
|
||||
|
||||
# All of our tests require C++17 or later
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "9.0.0"))
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "8.0.0"))
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.99")
|
||||
set(UNDEFINED_BEHAVIOR_WITHOUT_LINKING TRUE)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_FLAGS "-std=c++17")
|
||||
endif()
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.99"))
|
||||
@ -205,9 +208,10 @@ if(CXX_FILESYSTEM_HAVE_FS)
|
||||
]] code @ONLY)
|
||||
|
||||
# Try to compile a simple filesystem program without any linker flags
|
||||
check_cxx_source_compiles("${code}" CXX_FILESYSTEM_NO_LINK_NEEDED)
|
||||
|
||||
set(can_link ${CXX_FILESYSTEM_NO_LINK_NEEDED})
|
||||
if(NOT UNDEFINED_BEHAVIOR_WITHOUT_LINKING)
|
||||
check_cxx_source_compiles("${code}" CXX_FILESYSTEM_NO_LINK_NEEDED)
|
||||
set(can_link ${CXX_FILESYSTEM_NO_LINK_NEEDED})
|
||||
endif()
|
||||
|
||||
if(NOT CXX_FILESYSTEM_NO_LINK_NEEDED)
|
||||
set(prev_libraries ${CMAKE_REQUIRED_LIBRARIES})
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
Obs_Conf::Obs_Conf()
|
||||
{
|
||||
dump_filename = "obs_dump.dat";
|
||||
dump_filename = std::string("obs_dump.dat");
|
||||
smoothing_factor = FLAGS_carrier_smoothing_factor;
|
||||
nchannels_in = 0;
|
||||
nchannels_out = 0;
|
||||
|
@ -100,6 +100,8 @@ endif()
|
||||
|
||||
|
||||
set(SIGNAL_SOURCE_ADAPTER_SOURCES
|
||||
signal_source_base.cc
|
||||
file_source_base.cc
|
||||
file_signal_source.cc
|
||||
multichannel_file_signal_source.cc
|
||||
gen_signal_source.cc
|
||||
@ -114,6 +116,8 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES
|
||||
)
|
||||
|
||||
set(SIGNAL_SOURCE_ADAPTER_HEADERS
|
||||
signal_source_base.h
|
||||
file_source_base.h
|
||||
file_signal_source.h
|
||||
multichannel_file_signal_source.h
|
||||
gen_signal_source.h
|
||||
@ -164,6 +168,7 @@ target_link_libraries(signal_source_adapters
|
||||
Gnuradio::blocks
|
||||
signal_source_gr_blocks
|
||||
PRIVATE
|
||||
algorithms_libs
|
||||
gnss_sdr_flags
|
||||
core_system_parameters
|
||||
Glog::glog
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "ad9361_manager.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <iio.h>
|
||||
@ -42,9 +43,12 @@
|
||||
#include <vector>
|
||||
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *configuration,
|
||||
const std::string &role, unsigned int in_stream, unsigned int out_stream,
|
||||
Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused))) : role_(role), in_stream_(in_stream), out_stream_(out_stream)
|
||||
Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused)))
|
||||
: SignalSourceBase(configuration, role, "Ad9361_Fpga_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
|
||||
{
|
||||
const std::string default_gain_mode("slow_attack");
|
||||
const double default_tx_attenuation_db = -10.0;
|
||||
@ -98,22 +102,24 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
switch_position = configuration->property(role + ".switch_position", 0);
|
||||
if (switch_position != 0 && switch_position != 2)
|
||||
switch_position_ = configuration->property(role + ".switch_position", 0);
|
||||
if (switch_position_ != 0 && switch_position_ != 2)
|
||||
{
|
||||
std::cout << "SignalSource.switch_position configuration parameter must be either 0: read from file(s) via DMA, or 2: read from AD9361\n";
|
||||
std::cout << "SignalSource.switch_position configuration parameter set to its default value switch_position=0 - read from file(s)\n";
|
||||
switch_position = 0;
|
||||
switch_position_ = 0;
|
||||
}
|
||||
|
||||
switch_fpga = std::make_shared<Fpga_Switch>(device_io_name);
|
||||
switch_fpga->set_switch_position(switch_position);
|
||||
switch_fpga->set_switch_position(switch_position_);
|
||||
|
||||
item_size_ = sizeof(gr_complex);
|
||||
|
||||
std::cout << "Sample rate: " << sample_rate_ << " Sps\n";
|
||||
|
||||
if (switch_position == 0) // Inject file(s) via DMA
|
||||
enable_ovf_check_buffer_monitor_active_ = false; // check buffer overflow and buffer monitor disabled by default
|
||||
|
||||
if (switch_position_ == 0) // Inject file(s) via DMA
|
||||
{
|
||||
enable_DMA_ = true;
|
||||
const std::string empty_string;
|
||||
@ -154,7 +160,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
|
||||
freq_band = "L1L2";
|
||||
}
|
||||
}
|
||||
if (switch_position == 2) // Real-time via AD9361
|
||||
if (switch_position_ == 2) // Real-time via AD9361
|
||||
{
|
||||
// some basic checks
|
||||
if ((rf_port_select_ != "A_BALANCED") and (rf_port_select_ != "B_BALANCED") and (rf_port_select_ != "A_N") and (rf_port_select_ != "B_N") and (rf_port_select_ != "B_P") and (rf_port_select_ != "C_N") and (rf_port_select_ != "C_P") and (rf_port_select_ != "TX_MONITOR1") and (rf_port_select_ != "TX_MONITOR2") and (rf_port_select_ != "TX_MONITOR1_2"))
|
||||
@ -292,6 +298,26 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
|
||||
std::cout << "Exception cached when configuring the TX carrier: " << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
// when the receiver is working in real-time mode via AD9361 perform buffer overflow checking,
|
||||
// and if dump is enabled perform buffer monitoring
|
||||
enable_ovf_check_buffer_monitor_active_ = true;
|
||||
|
||||
std::string device_io_name_buffer_monitor;
|
||||
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
|
||||
// find the uio device file corresponding to the buffer monitor
|
||||
if (find_uio_dev_file_name(device_io_name_buffer_monitor, buffer_monitor_device_name, 0) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << buffer_monitor_device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
uint32_t num_freq_bands = (freq_band.compare("L1L2")) ? 1 : 2;
|
||||
buffer_monitor_fpga = std::make_shared<Fpga_buffer_monitor>(device_io_name_buffer_monitor, num_freq_bands, dump_, dump_filename);
|
||||
thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); });
|
||||
}
|
||||
|
||||
// dynamic bits selection
|
||||
@ -331,7 +357,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
|
||||
Ad9361FpgaSignalSource::~Ad9361FpgaSignalSource()
|
||||
{
|
||||
/* cleanup and exit */
|
||||
if (switch_position == 0) // read samples from a file via DMA
|
||||
if (switch_position_ == 0) // read samples from a file via DMA
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(dma_mutex);
|
||||
enable_DMA_ = false; // disable the DMA
|
||||
@ -342,7 +368,7 @@ Ad9361FpgaSignalSource::~Ad9361FpgaSignalSource()
|
||||
}
|
||||
}
|
||||
|
||||
if (switch_position == 2) // Real-time via AD9361
|
||||
if (switch_position_ == 2) // Real-time via AD9361
|
||||
{
|
||||
if (rf_shutdown_)
|
||||
{
|
||||
@ -363,6 +389,16 @@ Ad9361FpgaSignalSource::~Ad9361FpgaSignalSource()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// disable buffer overflow checking and buffer monitoring
|
||||
std::unique_lock<std::mutex> lock(buffer_monitor_mutex);
|
||||
enable_ovf_check_buffer_monitor_active_ = false;
|
||||
lock.unlock();
|
||||
|
||||
if (thread_buffer_monitor.joinable())
|
||||
{
|
||||
thread_buffer_monitor.join();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> lock(dynamic_bit_selection_mutex);
|
||||
@ -646,6 +682,25 @@ void Ad9361FpgaSignalSource::run_dynamic_bit_selection_process()
|
||||
}
|
||||
}
|
||||
|
||||
void Ad9361FpgaSignalSource::run_buffer_monitor_process()
|
||||
{
|
||||
bool enable_ovf_check_buffer_monitor_active = true;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitoring_initial_delay_ms));
|
||||
|
||||
while (enable_ovf_check_buffer_monitor_active)
|
||||
{
|
||||
buffer_monitor_fpga->check_buffer_overflow_and_monitor_buffer_status();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitor_period_ms));
|
||||
std::unique_lock<std::mutex> lock(buffer_monitor_mutex);
|
||||
if (enable_ovf_check_buffer_monitor_active_ == false)
|
||||
{
|
||||
enable_ovf_check_buffer_monitor_active = false;
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Ad9361FpgaSignalSource::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
|
@ -19,9 +19,11 @@
|
||||
#define GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "fpga_buffer_monitor.h"
|
||||
#include "fpga_dynamic_bit_selection.h"
|
||||
#include "fpga_switch.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <pmt/pmt.h>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
@ -38,7 +40,7 @@
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
class Ad9361FpgaSignalSource : public GNSSBlockInterface
|
||||
class Ad9361FpgaSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
Ad9361FpgaSignalSource(const ConfigurationInterface *configuration,
|
||||
@ -49,19 +51,6 @@ public:
|
||||
|
||||
void start() override;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Ad9361_Fpga_Signal_Source"
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Ad9361_Fpga_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -74,24 +63,30 @@ public:
|
||||
|
||||
private:
|
||||
const std::string switch_device_name = "AXIS_Switch_v1_0_0"; // Switch UIO device name
|
||||
const std::string dyn_bit_sel_device_name = "dynamic_bits_selector"; // Switch UIO device name
|
||||
|
||||
const std::string dyn_bit_sel_device_name = "dynamic_bits_selector"; // Switch dhnamic bit selector device name
|
||||
const std::string buffer_monitor_device_name = "buffer_monitor"; // buffer monitor device name
|
||||
const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat");
|
||||
// perform dynamic bit selection every 500 ms by default
|
||||
static const uint32_t Gain_control_period_ms = 500;
|
||||
// check buffer overflow and perform buffer monitoring every 1s by default
|
||||
static const uint32_t buffer_monitor_period_ms = 1000;
|
||||
// buffer overflow and buffer monitoring initial delay
|
||||
static const uint32_t buffer_monitoring_initial_delay_ms = 2000;
|
||||
|
||||
void run_DMA_process(const std::string &FreqBand,
|
||||
const std::string &Filename1,
|
||||
const std::string &Filename2);
|
||||
|
||||
void run_dynamic_bit_selection_process();
|
||||
void run_buffer_monitor_process();
|
||||
|
||||
std::thread thread_file_to_dma;
|
||||
std::thread thread_dynamic_bit_selection;
|
||||
std::thread thread_buffer_monitor;
|
||||
|
||||
std::shared_ptr<Fpga_Switch> switch_fpga;
|
||||
std::shared_ptr<Fpga_dynamic_bit_selection> dynamic_bit_selection_fpga;
|
||||
|
||||
std::string role_;
|
||||
std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga;
|
||||
|
||||
// Front-end settings
|
||||
std::string gain_mode_rx1_;
|
||||
@ -106,6 +101,7 @@ private:
|
||||
|
||||
std::mutex dma_mutex;
|
||||
std::mutex dynamic_bit_selection_mutex;
|
||||
std::mutex buffer_monitor_mutex;
|
||||
|
||||
double rf_gain_rx1_;
|
||||
double rf_gain_rx2_;
|
||||
@ -125,7 +121,7 @@ private:
|
||||
size_t item_size_;
|
||||
uint32_t in_stream_;
|
||||
uint32_t out_stream_;
|
||||
int32_t switch_position;
|
||||
int32_t switch_position_;
|
||||
bool enable_dds_lo_;
|
||||
|
||||
bool filter_auto_;
|
||||
@ -136,6 +132,9 @@ private:
|
||||
bool rx2_enable_;
|
||||
bool enable_DMA_;
|
||||
bool enable_dynamic_bit_selection_;
|
||||
bool enable_ovf_check_buffer_monitor_active_;
|
||||
bool enable_ovf_check_buffer_monitor_;
|
||||
bool dump_;
|
||||
bool rf_shutdown_;
|
||||
};
|
||||
|
||||
|
@ -17,13 +17,17 @@
|
||||
|
||||
#include "custom_udp_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include <glog/logging.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
CustomUDPSignalSource::CustomUDPSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role, unsigned int in_stream, unsigned int out_stream,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue __attribute__((unused))) : role_(role), in_stream_(in_stream), out_stream_(out_stream)
|
||||
Concurrent_Queue<pmt::pmt_t>* queue __attribute__((unused)))
|
||||
: SignalSourceBase(configuration, role, "Custom_UDP_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
|
||||
{
|
||||
// DUMP PARAMETERS
|
||||
const std::string default_dump_file("./data/signal_source.dat");
|
||||
|
@ -19,8 +19,8 @@
|
||||
#define GNSS_SDR_CUSTOM_UDP_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "gr_complex_ip_packet_source.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/null_sink.h>
|
||||
#include <pmt/pmt.h>
|
||||
@ -40,7 +40,7 @@ class ConfigurationInterface;
|
||||
* \brief This class reads from UDP packets, which streams interleaved
|
||||
* I/Q samples over a network.
|
||||
*/
|
||||
class CustomUDPSignalSource : public GNSSBlockInterface
|
||||
class CustomUDPSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
CustomUDPSignalSource(const ConfigurationInterface* configuration,
|
||||
@ -49,19 +49,6 @@ public:
|
||||
|
||||
~CustomUDPSignalSource() = default;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Custom_UDP_Signal_Source"
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Custom_UDP_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -78,7 +65,6 @@ private:
|
||||
std::vector<gnss_shared_ptr<gr::block>> null_sinks_;
|
||||
std::vector<gnss_shared_ptr<gr::block>> file_sink_;
|
||||
|
||||
std::string role_;
|
||||
std::string item_type_;
|
||||
std::string dump_filename_;
|
||||
|
||||
|
@ -10,343 +10,29 @@
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "file_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include <glog/logging.h>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream> // for std::cerr
|
||||
#include <utility>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
FileSignalSource::FileSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role, unsigned int in_streams, unsigned int out_streams,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
||||
FileSignalSource::FileSignalSource(ConfigurationInterface const* configuration,
|
||||
std::string const& role, unsigned int in_streams, unsigned int out_streams,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: FileSourceBase(configuration, role, "File_Signal_Source"s, queue, "short"s)
|
||||
{
|
||||
const std::string default_filename("./example_capture.dat");
|
||||
const std::string default_item_type("short");
|
||||
const std::string default_dump_filename("./my_capture.dat");
|
||||
|
||||
const double default_seconds_to_skip = 0.0;
|
||||
|
||||
samples_ = configuration->property(role + ".samples", static_cast<uint64_t>(0));
|
||||
sampling_frequency_ = configuration->property(role + ".sampling_frequency", static_cast<int64_t>(0));
|
||||
filename_ = configuration->property(role + ".filename", default_filename);
|
||||
|
||||
// override value with commandline flag, if present
|
||||
if (FLAGS_signal_source != "-")
|
||||
{
|
||||
filename_ = FLAGS_signal_source;
|
||||
}
|
||||
if (FLAGS_s != "-")
|
||||
{
|
||||
filename_ = FLAGS_s;
|
||||
}
|
||||
|
||||
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
||||
repeat_ = configuration->property(role + ".repeat", false);
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false);
|
||||
|
||||
const double seconds_to_skip = configuration->property(role + ".seconds_to_skip", default_seconds_to_skip);
|
||||
const size_t header_size = configuration->property(role + ".header_size", 0);
|
||||
int64_t samples_to_skip = 0;
|
||||
|
||||
bool is_complex = false;
|
||||
|
||||
if (item_type_ == "gr_complex")
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
}
|
||||
else if (item_type_ == "float")
|
||||
{
|
||||
item_size_ = sizeof(float);
|
||||
}
|
||||
else if (item_type_ == "short")
|
||||
{
|
||||
item_size_ = sizeof(int16_t);
|
||||
}
|
||||
else if (item_type_ == "ishort")
|
||||
{
|
||||
item_size_ = sizeof(int16_t);
|
||||
is_complex = true;
|
||||
}
|
||||
else if (item_type_ == "byte")
|
||||
{
|
||||
item_size_ = sizeof(int8_t);
|
||||
}
|
||||
else if (item_type_ == "ibyte")
|
||||
{
|
||||
item_size_ = sizeof(int8_t);
|
||||
is_complex = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_
|
||||
<< " unrecognized item type. Using gr_complex.";
|
||||
item_size_ = sizeof(gr_complex);
|
||||
}
|
||||
try
|
||||
{
|
||||
file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_);
|
||||
|
||||
if (seconds_to_skip > 0)
|
||||
{
|
||||
samples_to_skip = static_cast<int64_t>(seconds_to_skip * sampling_frequency_);
|
||||
|
||||
if (is_complex)
|
||||
{
|
||||
samples_to_skip *= 2;
|
||||
}
|
||||
}
|
||||
if (header_size > 0)
|
||||
{
|
||||
samples_to_skip += header_size;
|
||||
}
|
||||
|
||||
if (samples_to_skip > 0)
|
||||
{
|
||||
LOG(INFO) << "Skipping " << samples_to_skip << " samples of the input file";
|
||||
if (not file_source_->seek(samples_to_skip, SEEK_SET))
|
||||
{
|
||||
LOG(INFO) << "Error skipping bytes!";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
if (filename_ == default_filename)
|
||||
{
|
||||
std::cerr
|
||||
<< "The configuration file has not been found.\n"
|
||||
<< "Please create a configuration file based on the examples at the 'conf/' folder\n"
|
||||
<< "and then generate your own GNSS Software Defined Receiver by doing:\n"
|
||||
<< "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr
|
||||
<< "The receiver was configured to work with a file signal source\n"
|
||||
<< "but the specified file is unreachable by GNSS-SDR.\n"
|
||||
<< "Please modify your configuration file\n"
|
||||
<< "and point SignalSource.filename to a valid raw data file. Then:\n"
|
||||
<< "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf\n"
|
||||
<< "Examples of configuration files available at:\n"
|
||||
<< GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/\n";
|
||||
}
|
||||
|
||||
LOG(INFO) << "file_signal_source: Unable to open the samples file "
|
||||
<< filename_.c_str() << ", exiting the program.";
|
||||
throw(e);
|
||||
}
|
||||
|
||||
DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")";
|
||||
|
||||
if (samples_ == 0) // read all file
|
||||
{
|
||||
/*!
|
||||
* BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File.
|
||||
* A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the
|
||||
* valve block
|
||||
*/
|
||||
std::ifstream file(filename_.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
|
||||
std::ifstream::pos_type size;
|
||||
|
||||
if (file.is_open())
|
||||
{
|
||||
size = file.tellg();
|
||||
DLOG(INFO) << "Total samples in the file= " << floor(static_cast<double>(size) / static_cast<double>(item_size_));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "file_signal_source: Unable to open the samples file " << filename_.c_str() << '\n';
|
||||
LOG(ERROR) << "file_signal_source: Unable to open the samples file " << filename_.c_str();
|
||||
}
|
||||
std::streamsize ss = std::cout.precision();
|
||||
std::cout << std::setprecision(16);
|
||||
std::cout << "Processing file " << filename_ << ", which contains " << static_cast<double>(size) << " [bytes]\n";
|
||||
std::cout.precision(ss);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
const int64_t bytes_to_skip = samples_to_skip * item_size_;
|
||||
const int64_t bytes_to_process = static_cast<int64_t>(size) - bytes_to_skip;
|
||||
samples_ = floor(static_cast<double>(bytes_to_process) / static_cast<double>(item_size_) - ceil(0.002 * static_cast<double>(sampling_frequency_))); // process all the samples available in the file excluding at least the last 1 ms
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(samples_ > 0) << "File does not contain enough samples to process.";
|
||||
double signal_duration_s = static_cast<double>(samples_) * (1 / static_cast<double>(sampling_frequency_));
|
||||
|
||||
if (is_complex)
|
||||
{
|
||||
signal_duration_s /= 2.0;
|
||||
}
|
||||
|
||||
DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
|
||||
std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n";
|
||||
|
||||
valve_ = gnss_sdr_make_valve(item_size_, samples_, queue);
|
||||
DLOG(INFO) << "valve(" << valve_->unique_id() << ")";
|
||||
|
||||
if (dump_)
|
||||
{
|
||||
sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str());
|
||||
DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")";
|
||||
}
|
||||
|
||||
if (enable_throttle_control_)
|
||||
{
|
||||
throttle_ = gr::blocks::throttle::make(item_size_, sampling_frequency_);
|
||||
}
|
||||
|
||||
DLOG(INFO) << "File source filename " << filename_;
|
||||
DLOG(INFO) << "Samples " << samples_;
|
||||
DLOG(INFO) << "Sampling frequency " << sampling_frequency_;
|
||||
DLOG(INFO) << "Item type " << item_type_;
|
||||
DLOG(INFO) << "Item size " << item_size_;
|
||||
DLOG(INFO) << "Repeat " << repeat_;
|
||||
DLOG(INFO) << "Dump " << dump_;
|
||||
DLOG(INFO) << "Dump filename " << dump_filename_;
|
||||
if (in_streams_ > 0)
|
||||
if (in_streams > 0)
|
||||
{
|
||||
LOG(ERROR) << "A signal source does not have an input stream";
|
||||
}
|
||||
if (out_streams_ > 1)
|
||||
if (out_streams > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one output stream";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileSignalSource::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (samples_ > 0)
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->connect(file_source_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "connected file source to throttle";
|
||||
top_block->connect(throttle_, 0, valve_, 0);
|
||||
DLOG(INFO) << "connected throttle to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected valve to file sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
top_block->connect(file_source_, 0, valve_, 0);
|
||||
DLOG(INFO) << "connected file source to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected valve to file sink";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->connect(file_source_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "connected file source to throttle";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(file_source_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected file source to sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(file_source_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected file source to sink";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileSignalSource::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (samples_ > 0)
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "disconnected file source to throttle";
|
||||
top_block->disconnect(throttle_, 0, valve_, 0);
|
||||
DLOG(INFO) << "disconnected throttle to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected valve to file sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, valve_, 0);
|
||||
DLOG(INFO) << "disconnected file source to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected valve to file sink";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "disconnected file source to throttle";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected file source to sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected file source to sink";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr FileSignalSource::get_left_block()
|
||||
{
|
||||
LOG(WARNING) << "Left block of a signal source should not be retrieved";
|
||||
return gr::blocks::file_source::sptr();
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr FileSignalSource::get_right_block()
|
||||
{
|
||||
if (samples_ > 0)
|
||||
{
|
||||
return valve_;
|
||||
}
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
return throttle_;
|
||||
}
|
||||
return file_source_;
|
||||
}
|
||||
|
@ -21,15 +21,7 @@
|
||||
#ifndef GNSS_SDR_FILE_SIGNAL_SOURCE_H
|
||||
#define GNSS_SDR_FILE_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/throttle.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
#include <pmt/pmt.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include "file_source_base.h"
|
||||
|
||||
/** \addtogroup Signal_Source Signal Source
|
||||
* Classes for Signal Source management.
|
||||
@ -45,84 +37,16 @@ class ConfigurationInterface;
|
||||
* \brief Class that reads signals samples from a file
|
||||
* and adapts it to a SignalSourceInterface
|
||||
*/
|
||||
class FileSignalSource : public GNSSBlockInterface
|
||||
class FileSignalSource : public FileSourceBase
|
||||
{
|
||||
public:
|
||||
FileSignalSource(const ConfigurationInterface* configuration, const std::string& role,
|
||||
FileSignalSource(ConfigurationInterface const* configuration, std::string const& role,
|
||||
unsigned int in_streams, unsigned int out_streams,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue);
|
||||
|
||||
~FileSignalSource() = default;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "File_Signal_Source".
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "File_Signal_Source";
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
inline std::string filename() const
|
||||
{
|
||||
return filename_;
|
||||
}
|
||||
|
||||
inline std::string item_type() const
|
||||
{
|
||||
return item_type_;
|
||||
}
|
||||
|
||||
inline bool repeat() const
|
||||
{
|
||||
return repeat_;
|
||||
}
|
||||
|
||||
inline int64_t sampling_frequency() const
|
||||
{
|
||||
return sampling_frequency_;
|
||||
}
|
||||
|
||||
inline uint64_t samples() const
|
||||
{
|
||||
return samples_;
|
||||
}
|
||||
|
||||
private:
|
||||
gr::blocks::file_source::sptr file_source_;
|
||||
gnss_shared_ptr<gr::block> valve_;
|
||||
gr::blocks::file_sink::sptr sink_;
|
||||
gr::blocks::throttle::sptr throttle_;
|
||||
|
||||
std::string role_;
|
||||
std::string item_type_;
|
||||
std::string filename_;
|
||||
std::string dump_filename_;
|
||||
|
||||
uint64_t samples_;
|
||||
int64_t sampling_frequency_;
|
||||
size_t item_size_;
|
||||
|
||||
uint32_t in_streams_;
|
||||
uint32_t out_streams_;
|
||||
|
||||
bool enable_throttle_control_;
|
||||
bool repeat_;
|
||||
bool dump_;
|
||||
};
|
||||
|
||||
|
||||
|
506
src/algorithms/signal_source/adapters/file_source_base.cc
Normal file
506
src/algorithms/signal_source/adapters/file_source_base.cc
Normal file
@ -0,0 +1,506 @@
|
||||
/*!
|
||||
* \file file_source_base.cc
|
||||
* \brief Implementation of the base class for file-oriented signal_source GNSS blocks
|
||||
* \author Jim Melton, 2021. jim.melton(at)sncorp.com
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "file_source_base.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_filesystem.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include <glog/logging.h>
|
||||
#include <cmath> // ceil, floor
|
||||
#include <fstream>
|
||||
#include <utility> // move
|
||||
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
FileSourceBase::FileSourceBase(ConfigurationInterface const* configuration, std::string const& role, std::string impl,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue,
|
||||
std::string default_item_type)
|
||||
: SignalSourceBase(configuration, role, std::move(impl)), filename_(configuration->property(role + ".filename"s, "../data/example_capture.dat"s)),
|
||||
|
||||
file_source_(), // NOLINT
|
||||
|
||||
item_type_(configuration->property(role + ".item_type"s, default_item_type)), // NOLINT
|
||||
item_size_(0),
|
||||
is_complex_(false),
|
||||
|
||||
// apparently, MacOS (LLVM) finds 0UL ambiguous with bool, int64_t, uint64_t, int32_t, int16_t, uint16_t,... float, double
|
||||
header_size_(configuration->property(role + ".header_size"s, uint64_t(0))),
|
||||
seconds_to_skip_(configuration->property(role + ".seconds_to_skip"s, 0.0)),
|
||||
repeat_(configuration->property(role + ".repeat"s, false)),
|
||||
|
||||
samples_(configuration->property(role + ".samples"s, uint64_t(0))),
|
||||
sampling_frequency_(configuration->property(role + ".sampling_frequency"s, int64_t(0))),
|
||||
valve_(), // NOLINT
|
||||
queue_(queue),
|
||||
|
||||
enable_throttle_control_(configuration->property(role + ".enable_throttle_control"s, false)),
|
||||
throttle_(), // NOLINT
|
||||
|
||||
dump_(configuration->property(role + ".dump"s, false)),
|
||||
dump_filename_(configuration->property(role + ".dump_filename"s, "../data/my_capture.dat"s)),
|
||||
sink_() // NOLINT
|
||||
{
|
||||
// override value with commandline flag, if present
|
||||
if (FLAGS_signal_source != "-")
|
||||
{
|
||||
filename_ = FLAGS_signal_source;
|
||||
}
|
||||
if (FLAGS_s != "-")
|
||||
{
|
||||
filename_ = FLAGS_s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileSourceBase::init()
|
||||
{
|
||||
create_file_source();
|
||||
|
||||
// At this point, we know that the file exists
|
||||
samples_ = computeSamplesInFile();
|
||||
auto signal_duration_s = 1.0 * samples_ / sampling_frequency_;
|
||||
|
||||
if (is_complex())
|
||||
{
|
||||
signal_duration_s /= 2.0;
|
||||
}
|
||||
|
||||
DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
|
||||
std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n";
|
||||
|
||||
DLOG(INFO) << "File source filename " << filename_;
|
||||
DLOG(INFO) << "Samples " << samples_;
|
||||
DLOG(INFO) << "Sampling frequency " << sampling_frequency_;
|
||||
DLOG(INFO) << "Item type " << item_type_;
|
||||
DLOG(INFO) << "Item size " << item_size_;
|
||||
DLOG(INFO) << "Repeat " << repeat_;
|
||||
|
||||
DLOG(INFO) << "Dump " << dump_;
|
||||
DLOG(INFO) << "Dump filename " << dump_filename_;
|
||||
|
||||
create_throttle();
|
||||
create_valve();
|
||||
create_sink();
|
||||
}
|
||||
|
||||
|
||||
void FileSourceBase::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
init();
|
||||
pre_connect_hook(top_block);
|
||||
|
||||
auto input = gr::basic_block_sptr();
|
||||
auto output = gr::basic_block_sptr();
|
||||
|
||||
// THROTTLE
|
||||
if (throttle())
|
||||
{
|
||||
// if we are throttling...
|
||||
top_block->connect(source(), 0, throttle(), 0);
|
||||
DLOG(INFO) << "connected file source to throttle";
|
||||
|
||||
input = throttle();
|
||||
}
|
||||
else
|
||||
{
|
||||
// no throttle; let 'er rip
|
||||
input = source();
|
||||
}
|
||||
|
||||
// VALVE
|
||||
if (valve())
|
||||
{
|
||||
top_block->connect(input, 0, valve(), 0);
|
||||
DLOG(INFO) << "connected source to valve";
|
||||
|
||||
output = valve();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: dumping a file source is unlikely, but should this be the raw file source or the
|
||||
// throttle if there is one? I'm leaning towards "output=input"
|
||||
output = source(); // output = input;
|
||||
}
|
||||
|
||||
// DUMP
|
||||
if (sink())
|
||||
{
|
||||
top_block->connect(output, 0, sink(), 0);
|
||||
DLOG(INFO) << "connected output to file sink";
|
||||
}
|
||||
|
||||
post_connect_hook(top_block);
|
||||
}
|
||||
|
||||
|
||||
void FileSourceBase::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
auto input = gr::basic_block_sptr();
|
||||
auto output = gr::basic_block_sptr();
|
||||
|
||||
pre_disconnect_hook(top_block);
|
||||
|
||||
// THROTTLE
|
||||
if (throttle())
|
||||
{
|
||||
// if we are throttling...
|
||||
top_block->disconnect(source(), 0, throttle(), 0);
|
||||
DLOG(INFO) << "disconnected file source from throttle";
|
||||
|
||||
input = throttle();
|
||||
}
|
||||
else
|
||||
{
|
||||
// no throttle; let 'er rip
|
||||
input = source();
|
||||
}
|
||||
|
||||
// VALVE
|
||||
if (valve())
|
||||
{
|
||||
top_block->disconnect(input, 0, valve(), 0);
|
||||
DLOG(INFO) << "disconnected source to valve";
|
||||
|
||||
output = valve();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: dumping a file source is unlikely, but should this be the raw file source or the
|
||||
// throttle if there is one? I'm leaning towards "output=input"
|
||||
output = source(); // output = input;
|
||||
}
|
||||
|
||||
// DUMP
|
||||
if (sink())
|
||||
{
|
||||
top_block->disconnect(output, 0, sink(), 0);
|
||||
DLOG(INFO) << "disconnected output to file sink";
|
||||
}
|
||||
|
||||
post_disconnect_hook(top_block);
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr FileSourceBase::get_left_block()
|
||||
{
|
||||
// TODO: is this right? Shouldn't the left block be a nullptr?
|
||||
LOG(WARNING) << "Left block of a signal source should not be retrieved";
|
||||
return gr::blocks::file_source::sptr();
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr FileSourceBase::get_right_block()
|
||||
{
|
||||
// clang-tidy wants braces around the if-conditions. clang-format wants to break the braces into
|
||||
// multiple line blocks. It's much more readable this way
|
||||
// clang-format off
|
||||
if (valve_) { return valve_; }
|
||||
if (throttle_) { return throttle_; }
|
||||
return source();
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
|
||||
std::string FileSourceBase::filename() const
|
||||
{
|
||||
return filename_;
|
||||
}
|
||||
|
||||
|
||||
std::string FileSourceBase::item_type() const
|
||||
{
|
||||
return item_type_;
|
||||
}
|
||||
|
||||
|
||||
size_t FileSourceBase::item_size()
|
||||
{
|
||||
return item_size_;
|
||||
}
|
||||
|
||||
|
||||
size_t FileSourceBase::item_size() const
|
||||
{
|
||||
return item_size_;
|
||||
}
|
||||
|
||||
|
||||
bool FileSourceBase::repeat() const
|
||||
{
|
||||
return repeat_;
|
||||
}
|
||||
|
||||
|
||||
int64_t FileSourceBase::sampling_frequency() const
|
||||
{
|
||||
return sampling_frequency_;
|
||||
}
|
||||
|
||||
|
||||
uint64_t FileSourceBase::samples() const
|
||||
{
|
||||
return samples_;
|
||||
}
|
||||
|
||||
|
||||
std::tuple<size_t, bool> FileSourceBase::itemTypeToSize()
|
||||
{
|
||||
auto is_complex_t = false;
|
||||
auto item_size = size_t(0);
|
||||
|
||||
if (item_type_ == "gr_complex")
|
||||
{
|
||||
item_size = sizeof(gr_complex);
|
||||
}
|
||||
else if (item_type_ == "float")
|
||||
{
|
||||
item_size = sizeof(float);
|
||||
}
|
||||
else if (item_type_ == "short")
|
||||
{
|
||||
item_size = sizeof(int16_t);
|
||||
}
|
||||
else if (item_type_ == "ishort")
|
||||
{
|
||||
item_size = sizeof(int16_t);
|
||||
is_complex_t = true;
|
||||
}
|
||||
else if (item_type_ == "byte")
|
||||
{
|
||||
item_size = sizeof(int8_t);
|
||||
}
|
||||
else if (item_type_ == "ibyte")
|
||||
{
|
||||
item_size = sizeof(int8_t);
|
||||
is_complex_t = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_
|
||||
<< " unrecognized item type. Using gr_complex.";
|
||||
item_size = sizeof(gr_complex);
|
||||
}
|
||||
|
||||
return std::make_tuple(item_size, is_complex_t);
|
||||
}
|
||||
|
||||
|
||||
// Default case is one decoded packet per one read sample
|
||||
double FileSourceBase::packetsPerSample() const { return 1.0; }
|
||||
|
||||
|
||||
size_t FileSourceBase::samplesToSkip() const
|
||||
{
|
||||
auto samples_to_skip = size_t(0);
|
||||
|
||||
if (seconds_to_skip_ > 0)
|
||||
{
|
||||
// sampling_frequency is in terms of actual samples (output packets). If this source is
|
||||
// compressed, there may be multiple packets per file (read) sample. First compute the
|
||||
// actual number of samples to skip (function of time and sample rate)
|
||||
samples_to_skip = static_cast<size_t>(seconds_to_skip_ * sampling_frequency_);
|
||||
|
||||
// convert from sample to input items, scaling this value to input item space
|
||||
// (rounding up)
|
||||
samples_to_skip = std::ceil(samples_to_skip / packetsPerSample());
|
||||
|
||||
// complex inputs require two input items for one sample (arguably, packetsPerSample could be scaled by 0.5)
|
||||
if (is_complex())
|
||||
{
|
||||
samples_to_skip *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (header_size_ > 0)
|
||||
{
|
||||
samples_to_skip += header_size_;
|
||||
}
|
||||
|
||||
return samples_to_skip;
|
||||
}
|
||||
|
||||
|
||||
size_t FileSourceBase::computeSamplesInFile() const
|
||||
{
|
||||
auto n_samples = size_t(samples());
|
||||
|
||||
// if configured with 0 samples (read the whole file), figure out how many samples are in the file, and go from there
|
||||
if (n_samples == 0)
|
||||
{
|
||||
// this could throw, but the existence of the file has been proven before we get here.
|
||||
auto size = fs::file_size(filename());
|
||||
|
||||
// if there is some kind of compression/encoding, figure out the uncompressed number of samples
|
||||
n_samples = std::floor(packetsPerSample() * size / item_size());
|
||||
|
||||
auto to_skip = samplesToSkip();
|
||||
|
||||
/*!
|
||||
* BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File.
|
||||
* A possible solution is to compute the file length in samples using file size, excluding at least
|
||||
* the last 2 milliseconds, and enable always the valve block
|
||||
*/
|
||||
auto tail = static_cast<size_t>(std::ceil(0.002 * sampling_frequency()));
|
||||
|
||||
DLOG(INFO) << "Total samples in the file= " << n_samples;
|
||||
std::cout << "Processing file " << filename() << ", which contains " << n_samples << " samples (" << size << " bytes)\n";
|
||||
|
||||
if (n_samples > (to_skip + tail))
|
||||
{
|
||||
// process all the samples available in the file excluding up to the last 2 ms
|
||||
n_samples -= to_skip + tail;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this will terminate the program
|
||||
LOG(FATAL) << "Skipping " << to_skip << " samples from the front and truncating 2ms (" << tail << " samples)\n"
|
||||
<< "is greater than the number of samples in the file (" << n_samples << ")";
|
||||
}
|
||||
}
|
||||
|
||||
return n_samples;
|
||||
}
|
||||
|
||||
|
||||
size_t FileSourceBase::source_item_size() const
|
||||
{
|
||||
// delegate the size of the source to the source() object, so sub-classes have less work to do
|
||||
DLOG(INFO) << "source_item_size is " << source()->output_signature()->sizeof_stream_item(0);
|
||||
return source()->output_signature()->sizeof_stream_item(0);
|
||||
}
|
||||
|
||||
|
||||
bool FileSourceBase::is_complex() const { return is_complex_; }
|
||||
|
||||
|
||||
// Simple accessors
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::source() const { return file_source(); }
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::file_source() const { return file_source_; }
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::valve() const { return valve_; }
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::throttle() const { return throttle_; }
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::sink() const { return sink_; }
|
||||
|
||||
|
||||
gr::blocks::file_source::sptr FileSourceBase::create_file_source()
|
||||
{
|
||||
auto item_tuple = itemTypeToSize();
|
||||
item_size_ = std::get<0>(item_tuple);
|
||||
is_complex_ = std::get<1>(item_tuple);
|
||||
|
||||
try
|
||||
{
|
||||
// TODO: why are we manually seeking, instead of passing the samples_to_skip to the file_source factory?
|
||||
auto samples_to_skip = samplesToSkip();
|
||||
|
||||
file_source_ = gr::blocks::file_source::make(item_size(), filename().data(), repeat());
|
||||
|
||||
if (samples_to_skip > 0)
|
||||
{
|
||||
LOG(INFO) << "Skipping " << samples_to_skip << " samples of the input file";
|
||||
if (not file_source_->seek(samples_to_skip, SEEK_SET))
|
||||
{
|
||||
LOG(ERROR) << "Error skipping bytes!";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr
|
||||
<< "The receiver was configured to work with a file-based signal source\n"
|
||||
<< "but the specified file is unreachable by GNSS-SDR.\n"
|
||||
<< "[" << filename() << "]\n"
|
||||
<< "\n"
|
||||
<< "Please modify your configuration file\n"
|
||||
<< "and point SignalSource.filename to a valid raw data file. Then:\n"
|
||||
<< "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf\n"
|
||||
<< "Examples of configuration files available at:\n"
|
||||
<< GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/\n"
|
||||
<< std::endl;
|
||||
|
||||
LOG(ERROR) << "file_signal_source: Unable to open the samples file "
|
||||
<< filename() << ", exiting the program.";
|
||||
throw;
|
||||
}
|
||||
|
||||
DLOG(INFO) << implementation() << "(" << file_source_->unique_id() << ")";
|
||||
|
||||
// enable subclass hooks
|
||||
create_file_source_hook();
|
||||
|
||||
return file_source_;
|
||||
}
|
||||
|
||||
|
||||
gr::blocks::throttle::sptr FileSourceBase::create_throttle()
|
||||
{
|
||||
if (enable_throttle_control_)
|
||||
{
|
||||
// if we are throttling...
|
||||
throttle_ = gr::blocks::throttle::make(source_item_size(), sampling_frequency());
|
||||
DLOG(INFO) << "throttle(" << throttle_->unique_id() << ")";
|
||||
|
||||
// enable subclass hooks
|
||||
create_throttle_hook();
|
||||
}
|
||||
return throttle_;
|
||||
}
|
||||
|
||||
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::create_valve()
|
||||
{
|
||||
if (samples() > 0)
|
||||
{
|
||||
// if a number of samples is specified, honor it by creating a valve
|
||||
// In practice, this is always true
|
||||
valve_ = gnss_sdr_make_valve(source_item_size(), samples(), queue_);
|
||||
DLOG(INFO) << "valve(" << valve_->unique_id() << ")";
|
||||
|
||||
// enable subclass hooks
|
||||
create_valve_hook();
|
||||
}
|
||||
return valve_;
|
||||
}
|
||||
|
||||
|
||||
gr::blocks::file_sink::sptr FileSourceBase::create_sink()
|
||||
{
|
||||
if (dump_)
|
||||
{
|
||||
sink_ = gr::blocks::file_sink::make(source_item_size(), dump_filename_.c_str());
|
||||
DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")";
|
||||
|
||||
// enable subclass hooks
|
||||
create_sink_hook();
|
||||
}
|
||||
return sink_;
|
||||
}
|
||||
|
||||
|
||||
// Subclass hooks to augment created objects, as required
|
||||
void FileSourceBase::create_file_source_hook() {}
|
||||
void FileSourceBase::create_throttle_hook() {}
|
||||
void FileSourceBase::create_valve_hook() {}
|
||||
void FileSourceBase::create_sink_hook() {}
|
||||
|
||||
|
||||
// Subclass hooks for connection/disconnectino
|
||||
void FileSourceBase::pre_connect_hook(gr::top_block_sptr top_block [[maybe_unused]]) {}
|
||||
void FileSourceBase::post_connect_hook(gr::top_block_sptr top_block [[maybe_unused]]) {}
|
||||
void FileSourceBase::pre_disconnect_hook(gr::top_block_sptr top_block [[maybe_unused]]) {}
|
||||
void FileSourceBase::post_disconnect_hook(gr::top_block_sptr top_block [[maybe_unused]]) {}
|
186
src/algorithms/signal_source/adapters/file_source_base.h
Normal file
186
src/algorithms/signal_source/adapters/file_source_base.h
Normal file
@ -0,0 +1,186 @@
|
||||
/*!
|
||||
* \file file_source_base.h
|
||||
* \brief Header file of the base class to file-oriented signal_source GNSS blocks.
|
||||
* \author Jim Melton, 2021. jim.melton(at)sncorp.com
|
||||
*
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_FILE_SOURCE_BASE_H
|
||||
#define GNSS_SDR_FILE_SOURCE_BASE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/throttle.h>
|
||||
#include <pmt/pmt.h>
|
||||
#include <tuple>
|
||||
|
||||
// for dump
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
|
||||
//! \brief Base class to file-oriented SignalSourceBase GNSS blocks.
|
||||
//!
|
||||
//! This class supports the following properties:
|
||||
//!
|
||||
//! .filename - the path to the input file
|
||||
//! - may be overridden by the -signal_source or -s command-line arguments
|
||||
//!
|
||||
//! .samples - number of samples to process (default 0)
|
||||
//! - if not specified or 0, read the entire file; otherwise stop after that many samples
|
||||
//!
|
||||
//! .sampling_frequency - the frequency of the sampled data (samples/second)
|
||||
//!
|
||||
//! .item_type - data type of the samples (default "short")
|
||||
//!
|
||||
//! .header_size - the size of a prefixed header to skip in "samples" (default 0)
|
||||
//!
|
||||
//! .seconds_to_skip - number of seconds of lead-in data to skip over (default 0)
|
||||
//!
|
||||
//! .enable_throttle_control - whether to stop reading if the upstream buffer is full (default false)
|
||||
//!
|
||||
//! .repeat - whether to rewind and continue at end of file (default false)
|
||||
//!
|
||||
//! (probably abstracted to the base class)
|
||||
//!
|
||||
//! .dump - whether to archive input data
|
||||
//!
|
||||
//! .dump_filename - if dumping, path to file for output
|
||||
|
||||
|
||||
class FileSourceBase : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
// Virtual overrides
|
||||
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;
|
||||
|
||||
//! The file to read
|
||||
std::string filename() const;
|
||||
|
||||
//! The item type
|
||||
std::string item_type() const;
|
||||
|
||||
//! The configured size of each item
|
||||
size_t item_size() override;
|
||||
virtual size_t item_size() const; // what the interface **should** have declared
|
||||
|
||||
//! Whether to repeat reading after end-of-file
|
||||
bool repeat() const;
|
||||
|
||||
//! The sampling frequency of the source file
|
||||
int64_t sampling_frequency() const;
|
||||
|
||||
//! The number of samples in the file
|
||||
uint64_t samples() const;
|
||||
|
||||
protected:
|
||||
//! \brief Constructor
|
||||
//!
|
||||
//! Subclasses may want to assert default item types that are appropriate to the specific file
|
||||
//! type supported. Rather than require the item type to be specified in the config file, allow
|
||||
//! sub-classes to impose their will
|
||||
FileSourceBase(ConfigurationInterface const* configuration, std::string const& role, std::string impl,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue,
|
||||
std::string default_item_type = "short");
|
||||
|
||||
//! Perform post-construction initialization
|
||||
void init();
|
||||
|
||||
//! Compute the item size, from the item_type(). Subclasses may constrain types that don't make
|
||||
// sense. The return of this method is a tuple of item_size and is_complex
|
||||
virtual std::tuple<size_t, bool> itemTypeToSize();
|
||||
|
||||
//! The number of (possibly unpacked) samples in a (raw) file sample (default=1)
|
||||
virtual double packetsPerSample() const;
|
||||
|
||||
//! Compute the number of samples to skip
|
||||
virtual size_t samplesToSkip() const;
|
||||
|
||||
//! Compute the number of samples in the file
|
||||
size_t computeSamplesInFile() const;
|
||||
|
||||
//! Abstracted front-end source. Sub-classes may override if they create specialized chains to
|
||||
//! decode source files into a usable format
|
||||
virtual gnss_shared_ptr<gr::block> source() const;
|
||||
|
||||
//! For complex source chains, the size of the file item may not be the same as the size of the
|
||||
// "source" (decoded) item. This method allows subclasses to handle these differences
|
||||
virtual size_t source_item_size() const;
|
||||
bool is_complex() const;
|
||||
|
||||
// Generic access to created objects
|
||||
gnss_shared_ptr<gr::block> file_source() const;
|
||||
gnss_shared_ptr<gr::block> valve() const;
|
||||
gnss_shared_ptr<gr::block> throttle() const;
|
||||
gnss_shared_ptr<gr::block> sink() const;
|
||||
|
||||
// The methods create the various blocks, if enabled, and return access to them. The created
|
||||
// object is also held in this class
|
||||
gr::blocks::file_source::sptr create_file_source();
|
||||
gr::blocks::throttle::sptr create_throttle();
|
||||
gnss_shared_ptr<gr::block> create_valve();
|
||||
gr::blocks::file_sink::sptr create_sink();
|
||||
|
||||
// Subclass hooks to augment created objects, as required
|
||||
virtual void create_file_source_hook();
|
||||
virtual void create_throttle_hook();
|
||||
virtual void create_valve_hook();
|
||||
virtual void create_sink_hook();
|
||||
|
||||
// Subclass hooks for connection/disconnection
|
||||
virtual void pre_connect_hook(gr::top_block_sptr top_block);
|
||||
virtual void post_connect_hook(gr::top_block_sptr top_block);
|
||||
virtual void pre_disconnect_hook(gr::top_block_sptr top_block);
|
||||
virtual void post_disconnect_hook(gr::top_block_sptr top_block);
|
||||
|
||||
private:
|
||||
std::string filename_;
|
||||
gr::blocks::file_source::sptr file_source_;
|
||||
|
||||
std::string item_type_;
|
||||
size_t item_size_;
|
||||
bool is_complex_; // a misnomer; if I/Q are interleaved as integer values
|
||||
|
||||
size_t header_size_; // length (in samples) of the header (if any)
|
||||
double seconds_to_skip_;
|
||||
bool repeat_;
|
||||
|
||||
// The valve allows only the configured number of samples through, then it closes.
|
||||
|
||||
// The framework passes the queue as a naked pointer, rather than a shared pointer, so this
|
||||
// class has two choices: construct the valve in the ctor, or hold onto the pointer, possibly
|
||||
// beyond its lifetime. Fortunately, the queue is only used to create the valve, so the
|
||||
// likelihood of holding a stale pointer is mitigated
|
||||
uint64_t samples_;
|
||||
int64_t sampling_frequency_; // why is this signed
|
||||
gnss_shared_ptr<gr::block> valve_;
|
||||
Concurrent_Queue<pmt::pmt_t>* queue_;
|
||||
|
||||
bool enable_throttle_control_;
|
||||
gr::blocks::throttle::sptr throttle_;
|
||||
|
||||
bool dump_;
|
||||
std::string dump_filename_;
|
||||
gr::blocks::file_sink::sptr sink_;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -18,17 +18,21 @@
|
||||
|
||||
#include "flexiband_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <teleorbit/frontend.h>
|
||||
#include <utility>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
|
||||
FlexibandSignalSource::FlexibandSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role,
|
||||
unsigned int in_stream,
|
||||
unsigned int out_stream,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue __attribute__((unused))) : role_(role), in_stream_(in_stream), out_stream_(out_stream)
|
||||
Concurrent_Queue<pmt::pmt_t>* queue __attribute__((unused)))
|
||||
: SignalSourceBase(configuration, role, "Flexiband_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
|
||||
{
|
||||
const std::string default_item_type("byte");
|
||||
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
||||
|
@ -21,7 +21,7 @@
|
||||
#define GNSS_SDR_FLEXIBAND_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <gnuradio/blocks/char_to_float.h>
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/float_to_complex.h>
|
||||
@ -45,7 +45,7 @@ class ConfigurationInterface;
|
||||
* \brief This class configures and reads samples from Teleorbit Flexiband front-end.
|
||||
* This software requires a Flexiband GNU Radio driver installed (not included with GNSS-SDR).
|
||||
*/
|
||||
class FlexibandSignalSource : public GNSSBlockInterface
|
||||
class FlexibandSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
FlexibandSignalSource(const ConfigurationInterface* configuration,
|
||||
@ -54,19 +54,6 @@ public:
|
||||
|
||||
~FlexibandSignalSource() = default;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Flexiband_Signal_Source".
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Flexiband_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -85,7 +72,6 @@ private:
|
||||
std::vector<boost::shared_ptr<gr::block>> float_to_complex_;
|
||||
std::vector<gr::blocks::null_sink::sptr> null_sinks_;
|
||||
|
||||
std::string role_;
|
||||
std::string item_type_;
|
||||
std::string firmware_filename_;
|
||||
std::string signal_file;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ad9361_manager.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include <glog/logging.h>
|
||||
#include <algorithm> // for max
|
||||
@ -29,10 +30,12 @@
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
Fmcomms2SignalSource::Fmcomms2SignalSource(const ConfigurationInterface *configuration,
|
||||
const std::string &role, unsigned int in_stream, unsigned int out_stream,
|
||||
Concurrent_Queue<pmt::pmt_t> *queue) : role_(role), in_stream_(in_stream), out_stream_(out_stream)
|
||||
Concurrent_Queue<pmt::pmt_t> *queue)
|
||||
: SignalSourceBase(configuration, role, "Fmcomms2_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
|
||||
{
|
||||
const std::string default_item_type("gr_complex");
|
||||
const std::string default_dump_file("./data/signal_source.dat");
|
||||
|
@ -20,7 +20,7 @@
|
||||
#ifndef GNSS_SDR_FMCOMMS2_SIGNAL_SOURCE_H
|
||||
#define GNSS_SDR_FMCOMMS2_SIGNAL_SOURCE_H
|
||||
|
||||
#include "gnss_block_interface.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#if GRIIO_INCLUDE_HAS_GNURADIO
|
||||
#include <gnuradio/iio/fmcomms2_source.h>
|
||||
@ -41,7 +41,7 @@
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
class Fmcomms2SignalSource : public GNSSBlockInterface
|
||||
class Fmcomms2SignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
Fmcomms2SignalSource(const ConfigurationInterface* configuration,
|
||||
@ -50,19 +50,6 @@ public:
|
||||
|
||||
~Fmcomms2SignalSource();
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Fmcomms2_Signal_Source"
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Fmcomms2_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -78,7 +65,6 @@ private:
|
||||
gnss_shared_ptr<gr::block> valve_;
|
||||
gr::blocks::file_sink::sptr file_sink_;
|
||||
|
||||
std::string role_;
|
||||
std::string item_type_;
|
||||
std::string dump_filename_;
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "signal_source_interface.h"
|
||||
#include <pmt/pmt.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@ -37,16 +38,13 @@
|
||||
* \brief This class wraps blocks that generates synthesized GNSS signal and
|
||||
* filters the signal.
|
||||
*/
|
||||
class GenSignalSource : public GNSSBlockInterface
|
||||
class GenSignalSource : public SignalSourceInterface
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
GenSignalSource(std::shared_ptr<GNSSBlockInterface> signal_generator, std::shared_ptr<GNSSBlockInterface> filter,
|
||||
std::string role, Concurrent_Queue<pmt::pmt_t> *queue);
|
||||
|
||||
//! Virtual destructor
|
||||
virtual ~GenSignalSource() = default;
|
||||
|
||||
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;
|
||||
@ -56,6 +54,8 @@ public:
|
||||
//! Returns "Signal Source"
|
||||
inline std::string implementation() override { return "Signal Source"; }
|
||||
inline size_t item_size() override { return 0; }
|
||||
inline size_t getRfChannels() const final { return 0; }
|
||||
|
||||
inline std::shared_ptr<GNSSBlockInterface> signal_generator() const { return signal_generator_; }
|
||||
|
||||
private:
|
||||
|
@ -16,16 +16,20 @@
|
||||
|
||||
#include "gn3s_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gn3s/gn3s_source_cc.h>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
|
||||
Gn3sSignalSource::Gn3sSignalSource(const ConfigurationInterface* configuration,
|
||||
std::string role,
|
||||
unsigned int in_stream,
|
||||
unsigned int out_stream,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue) : role_(role), in_stream_(in_stream), out_stream_(out_stream)
|
||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: SignalSourceBase(configuration, role, "Gn3s_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
|
||||
{
|
||||
const std::string default_item_type("short");
|
||||
const std::string default_dump_file("./data/gn3s_source.dat");
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define GNSS_SDR_GN3S_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
#include <pmt/pmt.h>
|
||||
@ -38,7 +38,7 @@ class ConfigurationInterface;
|
||||
/*!
|
||||
* \brief This class reads samples from a GN3S USB dongle, a RF front-end signal sampler
|
||||
*/
|
||||
class Gn3sSignalSource : public GNSSBlockInterface
|
||||
class Gn3sSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
Gn3sSignalSource(const ConfigurationInterface* configuration,
|
||||
@ -47,19 +47,6 @@ public:
|
||||
|
||||
~Gn3sSignalSource() = default;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Gn3s_Signal_Source".
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Gn3s_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -73,11 +60,10 @@ public:
|
||||
private:
|
||||
gr::block_sptr gn3s_source_;
|
||||
gr::blocks::file_sink::sptr file_sink_;
|
||||
std::string role_;
|
||||
std::string item_type_;
|
||||
std::string dump_filename_;
|
||||
size_t item_size_;
|
||||
int64_t samples_;
|
||||
[[maybe_unused]] int64_t samples_;
|
||||
unsigned int in_stream_;
|
||||
unsigned int out_stream_;
|
||||
bool dump_;
|
||||
|
@ -16,14 +16,15 @@
|
||||
|
||||
#include "labsat_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include "labsat23_source.h"
|
||||
#include <glog/logging.h>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
LabsatSignalSource::LabsatSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role, unsigned int in_stream, unsigned int out_stream, Concurrent_Queue<pmt::pmt_t>* queue) : role_(role), in_stream_(in_stream), out_stream_(out_stream)
|
||||
const std::string& role, unsigned int in_stream, unsigned int out_stream, Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: SignalSourceBase(configuration, role, "Labsat_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
|
||||
{
|
||||
const std::string default_item_type("gr_complex");
|
||||
const std::string default_dump_file("./labsat_output.dat");
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/throttle.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
@ -38,7 +39,7 @@ class ConfigurationInterface;
|
||||
/*!
|
||||
* \brief This class reads samples stored by a LabSat 2 or LabSat 3 device
|
||||
*/
|
||||
class LabsatSignalSource : public GNSSBlockInterface
|
||||
class LabsatSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
LabsatSignalSource(const ConfigurationInterface* configuration,
|
||||
@ -47,19 +48,6 @@ public:
|
||||
|
||||
~LabsatSignalSource() = default;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Labsat_Signal_Source".
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Labsat_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -75,7 +63,6 @@ private:
|
||||
gr::blocks::file_sink::sptr file_sink_;
|
||||
gr::blocks::throttle::sptr throttle_;
|
||||
|
||||
std::string role_;
|
||||
std::string item_type_;
|
||||
std::string filename_;
|
||||
std::string dump_filename_;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "multichannel_file_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include <glog/logging.h>
|
||||
#include <exception>
|
||||
@ -27,18 +28,21 @@
|
||||
#include <utility>
|
||||
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
MultichannelFileSignalSource::MultichannelFileSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role, unsigned int in_streams, unsigned int out_streams,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: SignalSourceBase(configuration, role, "Multichannel_File_Signal_Source"s), in_streams_(in_streams), out_streams_(out_streams)
|
||||
{
|
||||
const std::string default_filename("./example_capture.dat");
|
||||
const std::string default_item_type("short");
|
||||
const std::string default_dump_filename("./my_capture.dat");
|
||||
const std::string default_filename("./example_capture.dat"s);
|
||||
const std::string default_item_type("short"s);
|
||||
const std::string default_dump_filename("./my_capture.dat"s);
|
||||
|
||||
const double default_seconds_to_skip = 0.0;
|
||||
samples_ = configuration->property(role + ".samples", static_cast<uint64_t>(0));
|
||||
sampling_frequency_ = configuration->property(role + ".sampling_frequency", static_cast<int64_t>(0));
|
||||
n_channels_ = configuration->property(role + ".total_channels", 1);
|
||||
samples_ = configuration->property(role + ".samples"s, static_cast<uint64_t>(0));
|
||||
sampling_frequency_ = configuration->property(role + ".sampling_frequency"s, static_cast<int64_t>(0));
|
||||
n_channels_ = configuration->property(role + ".total_channels"s, 1);
|
||||
|
||||
for (int32_t n = 0; n < n_channels_; n++)
|
||||
{
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/throttle.h>
|
||||
@ -45,7 +46,7 @@ class ConfigurationInterface;
|
||||
* \brief Class that reads signals samples from files at different frequency bands
|
||||
* and adapts it to a SignalSourceInterface
|
||||
*/
|
||||
class MultichannelFileSignalSource : public GNSSBlockInterface
|
||||
class MultichannelFileSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
MultichannelFileSignalSource(const ConfigurationInterface* configuration, const std::string& role,
|
||||
@ -54,19 +55,6 @@ public:
|
||||
|
||||
~MultichannelFileSignalSource() = default;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Multichannel_File_Signal_Source".
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Multichannel_File_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -109,7 +97,6 @@ private:
|
||||
std::vector<gr::blocks::throttle::sptr> throttle_vec_;
|
||||
std::vector<std::string> filename_vec_;
|
||||
std::string item_type_;
|
||||
std::string role_;
|
||||
uint64_t samples_;
|
||||
int64_t sampling_frequency_;
|
||||
size_t item_size_;
|
||||
|
@ -10,286 +10,69 @@
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "nsr_file_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include <glog/logging.h>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
NsrFileSignalSource::NsrFileSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role, unsigned int in_streams, unsigned int out_streams,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: FileSourceBase(configuration, role, "Nsr_File_Signal_Source"s, queue, "byte"s)
|
||||
{
|
||||
const std::string default_filename("../data/my_capture.dat");
|
||||
const std::string default_item_type("byte");
|
||||
const std::string default_dump_filename("../data/my_capture_dump.dat");
|
||||
|
||||
samples_ = configuration->property(role + ".samples", static_cast<uint64_t>(0));
|
||||
sampling_frequency_ = configuration->property(role + ".sampling_frequency", static_cast<int64_t>(0));
|
||||
filename_ = configuration->property(role + ".filename", default_filename);
|
||||
|
||||
// override value with commandline flag, if present
|
||||
if (FLAGS_signal_source != "-")
|
||||
{
|
||||
filename_ = FLAGS_signal_source;
|
||||
}
|
||||
if (FLAGS_s != "-")
|
||||
{
|
||||
filename_ = FLAGS_s;
|
||||
}
|
||||
|
||||
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
||||
repeat_ = configuration->property(role + ".repeat", false);
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false);
|
||||
|
||||
if (item_type_ == "byte")
|
||||
{
|
||||
item_size_ = sizeof(char);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_ << " unrecognized item type. Using byte.";
|
||||
item_size_ = sizeof(char);
|
||||
}
|
||||
try
|
||||
{
|
||||
file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_);
|
||||
unpack_byte_ = make_unpack_byte_2bit_samples();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr
|
||||
<< "The receiver was configured to work with a file signal source\n"
|
||||
<< "but the specified file is unreachable by GNSS-SDR.\n"
|
||||
<< "Please modify your configuration file\n"
|
||||
<< "and point SignalSource.filename to a valid raw data file. Then:\n"
|
||||
<< "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf\n"
|
||||
<< "Examples of configuration files available at:\n"
|
||||
<< GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/\n";
|
||||
|
||||
LOG(WARNING) << "file_signal_source: Unable to open the samples file "
|
||||
<< filename_.c_str() << ", exiting the program.";
|
||||
throw(e);
|
||||
}
|
||||
|
||||
DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")";
|
||||
|
||||
if (samples_ == 0) // read all file
|
||||
{
|
||||
/*!
|
||||
* BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File.
|
||||
* A possible solution is to compute the file length in samples using file size, excluding the last 2 milliseconds, and enable always the
|
||||
* valve block
|
||||
*/
|
||||
std::ifstream file(filename_.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
|
||||
std::ifstream::pos_type size;
|
||||
|
||||
if (file.is_open())
|
||||
{
|
||||
size = file.tellg();
|
||||
LOG(INFO) << "Total samples in the file= " << floor(static_cast<double>(size) / static_cast<double>(item_size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "file_signal_source: Unable to open the samples file " << filename_.c_str() << '\n';
|
||||
LOG(ERROR) << "file_signal_source: Unable to open the samples file " << filename_.c_str();
|
||||
}
|
||||
std::streamsize ss = std::cout.precision();
|
||||
std::cout << std::setprecision(16);
|
||||
std::cout << "Processing file " << filename_ << ", which contains " << size << " [bytes]\n";
|
||||
std::cout.precision(ss);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
int sample_packet_factor = 4; // 1 byte -> 4 samples
|
||||
samples_ = floor(static_cast<double>(size) / static_cast<double>(item_size())) * sample_packet_factor;
|
||||
samples_ = samples_ - ceil(0.002 * static_cast<double>(sampling_frequency_)); // process all the samples available in the file excluding the last 2 ms
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(samples_ > 0) << "File does not contain enough samples to process.";
|
||||
const double signal_duration_s = static_cast<double>(samples_) * (1 / static_cast<double>(sampling_frequency_));
|
||||
LOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
|
||||
std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n";
|
||||
|
||||
valve_ = gnss_sdr_make_valve(sizeof(float), samples_, queue);
|
||||
DLOG(INFO) << "valve(" << valve_->unique_id() << ")";
|
||||
|
||||
if (dump_)
|
||||
{
|
||||
// sink_ = gr_make_file_sink(item_size_, dump_filename_.c_str());
|
||||
sink_ = gr::blocks::file_sink::make(sizeof(float), dump_filename_.c_str());
|
||||
DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")";
|
||||
}
|
||||
|
||||
if (enable_throttle_control_)
|
||||
{
|
||||
throttle_ = gr::blocks::throttle::make(sizeof(float), sampling_frequency_);
|
||||
}
|
||||
DLOG(INFO) << "File source filename " << filename_;
|
||||
DLOG(INFO) << "Samples " << samples_;
|
||||
DLOG(INFO) << "Sampling frequency " << sampling_frequency_;
|
||||
DLOG(INFO) << "Item type " << item_type_;
|
||||
DLOG(INFO) << "Item size " << item_size_;
|
||||
DLOG(INFO) << "Repeat " << repeat_;
|
||||
DLOG(INFO) << "Dump " << dump_;
|
||||
DLOG(INFO) << "Dump filename " << dump_filename_;
|
||||
if (in_streams_ > 0)
|
||||
if (in_streams > 0)
|
||||
{
|
||||
LOG(ERROR) << "A signal source does not have an input stream";
|
||||
}
|
||||
if (out_streams_ > 1)
|
||||
if (out_streams > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one output stream";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NsrFileSignalSource::connect(gr::top_block_sptr top_block)
|
||||
std::tuple<size_t, bool> NsrFileSignalSource::itemTypeToSize()
|
||||
{
|
||||
if (samples_ > 0)
|
||||
auto is_complex = false;
|
||||
auto item_size = size_t(sizeof(char)); // default
|
||||
|
||||
if (item_type() == "byte")
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->connect(file_source_, 0, unpack_byte_, 0);
|
||||
top_block->connect(unpack_byte_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "connected file source to throttle";
|
||||
top_block->connect(throttle_, 0, valve_, 0);
|
||||
DLOG(INFO) << "connected throttle to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected valve to file sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
top_block->connect(file_source_, 0, unpack_byte_, 0);
|
||||
top_block->connect(unpack_byte_, 0, valve_, 0);
|
||||
DLOG(INFO) << "connected file source to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected valve to file sink";
|
||||
}
|
||||
}
|
||||
item_size = sizeof(char);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->connect(file_source_, 0, unpack_byte_, 0);
|
||||
top_block->connect(unpack_byte_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "connected file source to throttle";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(throttle_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected file source to sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(file_source_, 0, unpack_byte_, 0);
|
||||
top_block->connect(unpack_byte_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected file source to sink";
|
||||
}
|
||||
}
|
||||
LOG(WARNING) << item_type() << " unrecognized item type. Using byte.";
|
||||
}
|
||||
|
||||
return std::make_tuple(item_size, is_complex);
|
||||
}
|
||||
|
||||
// 1 byte -> 4 samples
|
||||
double NsrFileSignalSource::packetsPerSample() const { return 4.0; }
|
||||
gnss_shared_ptr<gr::block> NsrFileSignalSource::source() const { return unpack_byte_; }
|
||||
|
||||
void NsrFileSignalSource::disconnect(gr::top_block_sptr top_block)
|
||||
|
||||
void NsrFileSignalSource::create_file_source_hook()
|
||||
{
|
||||
if (samples_ > 0)
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, unpack_byte_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack_byte_";
|
||||
top_block->connect(unpack_byte_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "disconnected unpack_byte_ to throttle_";
|
||||
top_block->disconnect(throttle_, 0, valve_, 0);
|
||||
DLOG(INFO) << "disconnected throttle to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected valve to file sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, unpack_byte_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack_byte_";
|
||||
top_block->disconnect(unpack_byte_, 0, valve_, 0);
|
||||
DLOG(INFO) << "disconnected unpack_byte_ to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected valve to file sink";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, unpack_byte_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack_byte_";
|
||||
top_block->disconnect(unpack_byte_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "disconnected unpack_byte_ to throttle";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(unpack_byte_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected funpack_byte_ to sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, unpack_byte_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack_byte_";
|
||||
top_block->disconnect(unpack_byte_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected unpack_byte_ to sink";
|
||||
}
|
||||
}
|
||||
}
|
||||
unpack_byte_ = make_unpack_byte_2bit_samples();
|
||||
DLOG(INFO) << "unpack_byte_2bit_samples(" << unpack_byte_->unique_id() << ")";
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr NsrFileSignalSource::get_left_block()
|
||||
void NsrFileSignalSource::pre_connect_hook(gr::top_block_sptr top_block)
|
||||
{
|
||||
LOG(WARNING) << "Left block of a signal source should not be retrieved";
|
||||
// return gr_block_sptr();
|
||||
return gr::blocks::file_source::sptr();
|
||||
top_block->connect(file_source(), 0, unpack_byte_, 0);
|
||||
DLOG(INFO) << "connected file_source to unpacker";
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr NsrFileSignalSource::get_right_block()
|
||||
void NsrFileSignalSource::pre_disconnect_hook(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (samples_ > 0)
|
||||
{
|
||||
return valve_;
|
||||
}
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
return throttle_;
|
||||
}
|
||||
return unpack_byte_;
|
||||
top_block->disconnect(file_source(), 0, unpack_byte_, 0);
|
||||
DLOG(INFO) << "disconnected file_source from unpacker";
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
@ -21,15 +21,8 @@
|
||||
#ifndef GNSS_SDR_NSR_FILE_SIGNAL_SOURCE_H
|
||||
#define GNSS_SDR_NSR_FILE_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "file_source_base.h"
|
||||
#include "unpack_byte_2bit_samples.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/throttle.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
#include <pmt/pmt.h>
|
||||
#include <string>
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
* \{ */
|
||||
@ -42,7 +35,7 @@ class ConfigurationInterface;
|
||||
* \brief Class that reads signals samples from a file
|
||||
* and adapts it to a SignalSourceInterface
|
||||
*/
|
||||
class NsrFileSignalSource : public GNSSBlockInterface
|
||||
class NsrFileSignalSource : public FileSourceBase
|
||||
{
|
||||
public:
|
||||
NsrFileSignalSource(const ConfigurationInterface* configuration, const std::string& role,
|
||||
@ -50,73 +43,17 @@ public:
|
||||
Concurrent_Queue<pmt::pmt_t>* queue);
|
||||
|
||||
~NsrFileSignalSource() = default;
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Nsr_File_Signal_Source".
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Nsr_File_Signal_Source";
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
inline std::string filename() const
|
||||
{
|
||||
return filename_;
|
||||
}
|
||||
|
||||
inline std::string item_type() const
|
||||
{
|
||||
return item_type_;
|
||||
}
|
||||
|
||||
inline bool repeat() const
|
||||
{
|
||||
return repeat_;
|
||||
}
|
||||
|
||||
inline int64_t sampling_frequency() const
|
||||
{
|
||||
return sampling_frequency_;
|
||||
}
|
||||
|
||||
inline uint64_t samples() const
|
||||
{
|
||||
return samples_;
|
||||
}
|
||||
protected:
|
||||
std::tuple<size_t, bool> itemTypeToSize() override;
|
||||
double packetsPerSample() const override;
|
||||
gnss_shared_ptr<gr::block> source() const override;
|
||||
void create_file_source_hook() override;
|
||||
void pre_connect_hook(gr::top_block_sptr top_block) override;
|
||||
void pre_disconnect_hook(gr::top_block_sptr top_block) override;
|
||||
|
||||
private:
|
||||
gr::blocks::file_source::sptr file_source_;
|
||||
unpack_byte_2bit_samples_sptr unpack_byte_;
|
||||
gnss_shared_ptr<gr::block> valve_;
|
||||
gr::blocks::file_sink::sptr sink_;
|
||||
gr::blocks::throttle::sptr throttle_;
|
||||
uint64_t samples_;
|
||||
int64_t sampling_frequency_;
|
||||
size_t item_size_;
|
||||
std::string filename_;
|
||||
std::string item_type_;
|
||||
std::string dump_filename_;
|
||||
std::string role_;
|
||||
uint32_t in_streams_;
|
||||
uint32_t out_streams_;
|
||||
bool repeat_;
|
||||
bool dump_;
|
||||
// Throttle control
|
||||
bool enable_throttle_control_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "osmosdr_signal_source.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
@ -25,9 +26,13 @@
|
||||
#include <utility>
|
||||
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
|
||||
OsmosdrSignalSource::OsmosdrSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role, unsigned int in_stream, unsigned int out_stream,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue) : role_(role), in_stream_(in_stream), out_stream_(out_stream)
|
||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: SignalSourceBase(configuration, role, "Osmosdr_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
|
||||
{
|
||||
// DUMP PARAMETERS
|
||||
const std::string empty;
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define GNSS_SDR_OSMOSDR_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <pmt/pmt.h>
|
||||
#include <cstdint>
|
||||
@ -42,7 +42,7 @@ class ConfigurationInterface;
|
||||
* HackRF or Realtek's RTL2832U-based USB dongle DVB-T receivers
|
||||
* (see https://osmocom.org/projects/rtl-sdr/wiki)
|
||||
*/
|
||||
class OsmosdrSignalSource : public GNSSBlockInterface
|
||||
class OsmosdrSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
OsmosdrSignalSource(const ConfigurationInterface* configuration,
|
||||
@ -51,19 +51,6 @@ public:
|
||||
|
||||
~OsmosdrSignalSource() = default;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Osmosdr_Signal_Source"
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Osmosdr_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -81,7 +68,6 @@ private:
|
||||
gnss_shared_ptr<gr::block> valve_;
|
||||
gr::blocks::file_sink::sptr file_sink_;
|
||||
|
||||
std::string role_;
|
||||
std::string item_type_;
|
||||
std::string dump_filename_;
|
||||
std::string osmosdr_args_;
|
||||
|
@ -18,15 +18,20 @@
|
||||
#include "plutosdr_signal_source.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include <glog/logging.h>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
|
||||
PlutosdrSignalSource::PlutosdrSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role, unsigned int in_stream, unsigned int out_stream,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue) : role_(role), in_stream_(in_stream), out_stream_(out_stream)
|
||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: SignalSourceBase(configuration, role, "Plutosdr_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
|
||||
{
|
||||
const std::string default_item_type("gr_complex");
|
||||
const std::string default_dump_file("./data/signal_source.dat");
|
||||
|
@ -19,7 +19,7 @@
|
||||
#ifndef GNSS_SDR_PLUTOSDR_SIGNAL_SOURCE_H
|
||||
#define GNSS_SDR_PLUTOSDR_SIGNAL_SOURCE_H
|
||||
|
||||
#include "gnss_block_interface.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#if GRIIO_INCLUDE_HAS_GNURADIO
|
||||
#include <gnuradio/iio/pluto_source.h>
|
||||
@ -42,7 +42,7 @@ class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
*/
|
||||
class PlutosdrSignalSource : public GNSSBlockInterface
|
||||
class PlutosdrSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
PlutosdrSignalSource(const ConfigurationInterface* configuration,
|
||||
@ -51,18 +51,6 @@ public:
|
||||
|
||||
~PlutosdrSignalSource() = default;
|
||||
|
||||
std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Plutosdr_Signal_Source"
|
||||
*/
|
||||
std::string implementation() override
|
||||
{
|
||||
return "Plutosdr_Signal_Source";
|
||||
}
|
||||
size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -79,7 +67,6 @@ private:
|
||||
gnss_shared_ptr<gr::block> valve_;
|
||||
gr::blocks::file_sink::sptr file_sink_;
|
||||
|
||||
std::string role_;
|
||||
std::string dump_filename_;
|
||||
|
||||
// Front-end settings
|
||||
|
@ -17,14 +17,18 @@
|
||||
#include "raw_array_signal_source.h"
|
||||
#include "concurrent_queue.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <pmt/pmt.h>
|
||||
#include <dbfcttc/raw_array.h>
|
||||
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
RawArraySignalSource::RawArraySignalSource(const ConfigurationInterface* configuration,
|
||||
std::string role, unsigned int in_stream, unsigned int out_stream, Concurrent_Queue<pmt::pmt_t>* queue) : role_(role), in_stream_(in_stream), out_stream_(out_stream)
|
||||
std::string role, unsigned int in_stream, unsigned int out_stream, Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: SignalSourceBase(configuration, role, "Raw_Array_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
|
||||
{
|
||||
const std::string default_item_type("gr_complex");
|
||||
const std::string default_dump_file("./data/raw_array_source.dat");
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define GNSS_SDR_RAW_ARRAY_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
#include <pmt/pmt.h>
|
||||
@ -39,7 +39,7 @@ class ConfigurationInterface;
|
||||
/*!
|
||||
* \brief This class reads samples from a GN3S USB dongle, a RF front-end signal sampler
|
||||
*/
|
||||
class RawArraySignalSource : public GNSSBlockInterface
|
||||
class RawArraySignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
RawArraySignalSource(const ConfigurationInterface* configuration,
|
||||
@ -48,19 +48,6 @@ public:
|
||||
|
||||
~RawArraySignalSource() = default;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "RawArraySignalSource".
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Raw_Array_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -74,12 +61,11 @@ public:
|
||||
private:
|
||||
gr::block_sptr raw_array_source_;
|
||||
gr::blocks::file_sink::sptr file_sink_;
|
||||
std::string role_;
|
||||
std::string item_type_;
|
||||
std::string dump_filename_;
|
||||
std::string eth_device_;
|
||||
size_t item_size_;
|
||||
int64_t samples_;
|
||||
[[maybe_unused]] int64_t samples_;
|
||||
unsigned int in_stream_;
|
||||
unsigned int out_stream_;
|
||||
bool dump_;
|
||||
|
@ -19,20 +19,21 @@
|
||||
#include "rtl_tcp_signal_source.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include <glog/logging.h>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
RtlTcpSignalSource::RtlTcpSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role,
|
||||
unsigned int in_stream,
|
||||
unsigned int out_stream,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue) : role_(role),
|
||||
in_stream_(in_stream),
|
||||
out_stream_(out_stream)
|
||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: SignalSourceBase(configuration, role, "RtlTcp_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
|
||||
{
|
||||
// DUMP PARAMETERS
|
||||
const std::string default_dump_file("./data/signal_source.dat");
|
||||
|
@ -19,8 +19,8 @@
|
||||
#define GNSS_SDR_RTL_TCP_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "rtl_tcp_signal_source_c.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <gnuradio/blocks/deinterleave.h>
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/float_to_complex.h>
|
||||
@ -42,7 +42,7 @@ class ConfigurationInterface;
|
||||
* I/Q samples over TCP.
|
||||
* (see https://osmocom.org/projects/rtl-sdr/wiki)
|
||||
*/
|
||||
class RtlTcpSignalSource : public GNSSBlockInterface
|
||||
class RtlTcpSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
RtlTcpSignalSource(const ConfigurationInterface* configuration,
|
||||
@ -53,19 +53,6 @@ public:
|
||||
|
||||
~RtlTcpSignalSource() = default;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "RtlTcp_Signal_Source"
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "RtlTcp_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -84,7 +71,6 @@ private:
|
||||
gnss_shared_ptr<gr::block> valve_;
|
||||
gr::blocks::file_sink::sptr file_sink_;
|
||||
|
||||
std::string role_;
|
||||
std::string item_type_;
|
||||
std::string dump_filename_;
|
||||
|
||||
|
46
src/algorithms/signal_source/adapters/signal_source_base.cc
Normal file
46
src/algorithms/signal_source/adapters/signal_source_base.cc
Normal file
@ -0,0 +1,46 @@
|
||||
/*!
|
||||
* \file signal_source_base.cc
|
||||
* \brief Base class for signal sources
|
||||
* \author Jim Melton, 2020. jim.melton(at)sncorp.com
|
||||
*
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "signal_source_base.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include <utility> // move
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
std::string SignalSourceBase::role()
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
std::string SignalSourceBase::implementation()
|
||||
{
|
||||
return implementation_;
|
||||
}
|
||||
|
||||
size_t SignalSourceBase::getRfChannels() const
|
||||
{
|
||||
return rfChannels_;
|
||||
}
|
||||
|
||||
SignalSourceBase::SignalSourceBase(ConfigurationInterface const* configuration, std::string role, std::string impl)
|
||||
: role_(std::move(role)), implementation_(std::move(impl))
|
||||
{
|
||||
// because clang-tidy insists on using std::move for the string arguments, and to avoid
|
||||
// depending on the order of initialization, assign rfChannels_ in the body
|
||||
rfChannels_ = configuration->property(role_ + ".RF_channels"s, uint64_t(1U));
|
||||
}
|
47
src/algorithms/signal_source/adapters/signal_source_base.h
Normal file
47
src/algorithms/signal_source/adapters/signal_source_base.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*!
|
||||
* \file signal_source_base.h
|
||||
* \brief Header file of the base class to signal_source GNSS blocks.
|
||||
* \author Jim Melton, 2020. jim.melton(at)sncorp.com
|
||||
*
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_SIGNAL_SOURCE_BASE_H
|
||||
#define GNSS_SDR_SIGNAL_SOURCE_BASE_H
|
||||
|
||||
#include "signal_source_interface.h"
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
class SignalSourceBase : public SignalSourceInterface
|
||||
{
|
||||
public:
|
||||
std::string role() final;
|
||||
std::string implementation() final;
|
||||
|
||||
size_t getRfChannels() const override;
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
SignalSourceBase(ConfigurationInterface const* configuration, std::string role, std::string impl);
|
||||
|
||||
private:
|
||||
std::string const role_;
|
||||
std::string const implementation_;
|
||||
size_t rfChannels_;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -6,290 +6,74 @@
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is not part of GNSS-SDR.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "spir_file_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include <glog/logging.h>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
SpirFileSignalSource::SpirFileSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role, unsigned int in_streams, unsigned int out_streams,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: FileSourceBase(configuration, role, "Spir_File_Signal_Source"s, queue, "int"s)
|
||||
{
|
||||
const std::string default_filename("../data/my_capture.dat");
|
||||
const std::string default_item_type("int");
|
||||
const std::string default_dump_filename("../data/my_capture_dump.dat");
|
||||
|
||||
samples_ = configuration->property(role + ".samples", static_cast<uint64_t>(0));
|
||||
sampling_frequency_ = configuration->property(role + ".sampling_frequency", static_cast<int64_t>(0));
|
||||
filename_ = configuration->property(role + ".filename", default_filename);
|
||||
|
||||
// override value with commandline flag, if present
|
||||
if (FLAGS_signal_source != "-")
|
||||
{
|
||||
filename_ = FLAGS_signal_source;
|
||||
}
|
||||
if (FLAGS_s != "-")
|
||||
{
|
||||
filename_ = FLAGS_s;
|
||||
}
|
||||
|
||||
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
||||
repeat_ = configuration->property(role + ".repeat", false);
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false);
|
||||
|
||||
if (item_type_ == "int")
|
||||
{
|
||||
item_size_ = sizeof(int);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_ << " unrecognized item type. Using int.";
|
||||
item_size_ = sizeof(int);
|
||||
}
|
||||
try
|
||||
{
|
||||
file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_);
|
||||
unpack_intspir_ = make_unpack_intspir_1bit_samples();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr
|
||||
<< "The receiver was configured to work with a file signal source\n"
|
||||
<< "but the specified file is unreachable by GNSS-SDR.\n"
|
||||
<< "Please modify your configuration file\n"
|
||||
<< "and point SignalSource.filename to a valid raw data file. Then:\n"
|
||||
<< "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf\n"
|
||||
<< "Examples of configuration files available at:\n"
|
||||
<< GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/\n";
|
||||
|
||||
LOG(WARNING) << "file_signal_source: Unable to open the samples file "
|
||||
<< filename_.c_str() << ", exiting the program.";
|
||||
throw(e);
|
||||
}
|
||||
|
||||
DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")";
|
||||
|
||||
if (samples_ == 0) // read all file
|
||||
{
|
||||
/*!
|
||||
* BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File.
|
||||
* A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the
|
||||
* valve block
|
||||
*/
|
||||
std::ifstream file(filename_.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
|
||||
std::ifstream::pos_type size;
|
||||
|
||||
if (file.is_open())
|
||||
{
|
||||
size = file.tellg();
|
||||
LOG(INFO) << "Total samples in the file= " << floor(static_cast<double>(size) / static_cast<double>(item_size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "file_signal_source: Unable to open the samples file " << filename_.c_str() << '\n';
|
||||
LOG(ERROR) << "file_signal_source: Unable to open the samples file " << filename_.c_str();
|
||||
}
|
||||
std::streamsize ss = std::cout.precision();
|
||||
std::cout << std::setprecision(16);
|
||||
std::cout << "Processing file " << filename_ << ", which contains " << size << " [bytes]\n";
|
||||
std::cout.precision(ss);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
int sample_packet_factor = 1; // 1 int -> 1 complex sample (I&Q from 1 channel)
|
||||
samples_ = floor(static_cast<double>(size) / static_cast<double>(item_size())) * sample_packet_factor;
|
||||
samples_ = samples_ - ceil(0.002 * static_cast<double>(sampling_frequency_)); // process all the samples available in the file excluding the last 2 ms
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(samples_ > 0) << "File does not contain enough samples to process.";
|
||||
double signal_duration_s = static_cast<double>(samples_) * (1 / static_cast<double>(sampling_frequency_));
|
||||
LOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
|
||||
std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n";
|
||||
|
||||
valve_ = gnss_sdr_make_valve(sizeof(float), samples_, queue);
|
||||
DLOG(INFO) << "valve(" << valve_->unique_id() << ")";
|
||||
|
||||
if (dump_)
|
||||
{
|
||||
// sink_ = gr_make_file_sink(item_size_, dump_filename_.c_str());
|
||||
sink_ = gr::blocks::file_sink::make(sizeof(float), dump_filename_.c_str());
|
||||
DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")";
|
||||
}
|
||||
|
||||
if (enable_throttle_control_)
|
||||
{
|
||||
throttle_ = gr::blocks::throttle::make(sizeof(float), sampling_frequency_);
|
||||
}
|
||||
DLOG(INFO) << "File source filename " << filename_;
|
||||
DLOG(INFO) << "Samples " << samples_;
|
||||
DLOG(INFO) << "Sampling frequency " << sampling_frequency_;
|
||||
DLOG(INFO) << "Item type " << item_type_;
|
||||
DLOG(INFO) << "Item size " << item_size_;
|
||||
DLOG(INFO) << "Repeat " << repeat_;
|
||||
DLOG(INFO) << "Dump " << dump_;
|
||||
DLOG(INFO) << "Dump filename " << dump_filename_;
|
||||
if (in_streams_ > 0)
|
||||
if (in_streams > 0)
|
||||
{
|
||||
LOG(ERROR) << "A signal source does not have an input stream";
|
||||
}
|
||||
if (out_streams_ > 1)
|
||||
if (out_streams > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one output stream";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SpirFileSignalSource::connect(gr::top_block_sptr top_block)
|
||||
std::tuple<size_t, bool> SpirFileSignalSource::itemTypeToSize()
|
||||
{
|
||||
if (samples_ > 0)
|
||||
auto is_complex = false;
|
||||
auto item_size = size_t(0);
|
||||
|
||||
if (item_type() == "int")
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->connect(file_source_, 0, unpack_intspir_, 0);
|
||||
top_block->connect(unpack_intspir_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "connected file source to throttle";
|
||||
top_block->connect(throttle_, 0, valve_, 0);
|
||||
DLOG(INFO) << "connected throttle to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected valve to file sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
top_block->connect(file_source_, 0, unpack_intspir_, 0);
|
||||
top_block->connect(unpack_intspir_, 0, valve_, 0);
|
||||
DLOG(INFO) << "connected file source to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected valve to file sink";
|
||||
}
|
||||
}
|
||||
item_size = sizeof(int);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->connect(file_source_, 0, unpack_intspir_, 0);
|
||||
top_block->connect(unpack_intspir_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "connected file source to throttle";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(throttle_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected file source to sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(file_source_, 0, unpack_intspir_, 0);
|
||||
top_block->connect(unpack_intspir_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected file source to sink";
|
||||
}
|
||||
}
|
||||
LOG(WARNING) << item_type() << " unsupported item type. Using int.";
|
||||
item_size = sizeof(int);
|
||||
}
|
||||
|
||||
return std::make_tuple(item_size, is_complex);
|
||||
}
|
||||
|
||||
// This class feeds the file data through a decoder to produce samples; for all intents this is the "source"
|
||||
gnss_shared_ptr<gr::block> SpirFileSignalSource::source() const { return unpack_intspir_; }
|
||||
|
||||
void SpirFileSignalSource::disconnect(gr::top_block_sptr top_block)
|
||||
|
||||
void SpirFileSignalSource::create_file_source_hook()
|
||||
{
|
||||
if (samples_ > 0)
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, unpack_intspir_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack_intspir_";
|
||||
top_block->connect(unpack_intspir_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "disconnected unpack_intspir_ to throttle_";
|
||||
top_block->disconnect(throttle_, 0, valve_, 0);
|
||||
DLOG(INFO) << "disconnected throttle to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected valve to file sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, unpack_intspir_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack_intspir_";
|
||||
top_block->disconnect(unpack_intspir_, 0, valve_, 0);
|
||||
DLOG(INFO) << "disconnected unpack_intspir_ to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected valve to file sink";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, unpack_intspir_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack_intspir_";
|
||||
top_block->disconnect(unpack_intspir_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "disconnected unpack_intspir_ to throttle";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(unpack_intspir_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected funpack_intspir_ to sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, unpack_intspir_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack_intspir_";
|
||||
top_block->disconnect(unpack_intspir_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected unpack_intspir_ to sink";
|
||||
}
|
||||
}
|
||||
}
|
||||
// connect the file to the decoder
|
||||
unpack_intspir_ = make_unpack_intspir_1bit_samples();
|
||||
DLOG(INFO) << "unpack_intspir_1bit_samples(" << unpack_intspir_->unique_id() << ")";
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr SpirFileSignalSource::get_left_block()
|
||||
void SpirFileSignalSource::pre_connect_hook(gr::top_block_sptr top_block)
|
||||
{
|
||||
LOG(WARNING) << "Left block of a signal source should not be retrieved";
|
||||
// return gr_block_sptr();
|
||||
return gr::blocks::file_source::sptr();
|
||||
top_block->connect(file_source(), 0, unpack_intspir_, 0);
|
||||
DLOG(INFO) << "connected file_source to unpacker";
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr SpirFileSignalSource::get_right_block()
|
||||
void SpirFileSignalSource::post_disconnect_hook(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (samples_ > 0)
|
||||
{
|
||||
return valve_;
|
||||
}
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
return throttle_;
|
||||
}
|
||||
return unpack_intspir_;
|
||||
top_block->disconnect(file_source(), 0, unpack_intspir_, 0);
|
||||
DLOG(INFO) << "disconnected file_source from unpacker";
|
||||
}
|
||||
|
@ -6,13 +6,10 @@
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
*
|
||||
* This file is not part of GNSS-SDR.
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
@ -21,16 +18,8 @@
|
||||
#ifndef GNSS_SDR_SPIR_FILE_SIGNAL_SOURCE_H
|
||||
#define GNSS_SDR_SPIR_FILE_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "file_source_base.h"
|
||||
#include "unpack_intspir_1bit_samples.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/throttle.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
#include <pmt/pmt.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
@ -45,7 +34,7 @@ class ConfigurationInterface;
|
||||
* \brief Class that reads signals samples from a file
|
||||
* and adapts it to a SignalSourceInterface
|
||||
*/
|
||||
class SpirFileSignalSource : public GNSSBlockInterface
|
||||
class SpirFileSignalSource : public FileSourceBase
|
||||
{
|
||||
public:
|
||||
SpirFileSignalSource(const ConfigurationInterface* configuration, const std::string& role,
|
||||
@ -54,77 +43,16 @@ public:
|
||||
|
||||
~SpirFileSignalSource() = default;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
protected:
|
||||
std::tuple<size_t, bool> itemTypeToSize() override;
|
||||
gnss_shared_ptr<gr::block> source() const override;
|
||||
void create_file_source_hook() override;
|
||||
void pre_connect_hook(gr::top_block_sptr top_block) override;
|
||||
void post_disconnect_hook(gr::top_block_sptr top_block) override;
|
||||
|
||||
/*!
|
||||
* \brief Returns "Spir_File_Signal_Source".
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Spir_File_Signal_Source";
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
inline std::string filename() const
|
||||
{
|
||||
return filename_;
|
||||
}
|
||||
|
||||
inline std::string item_type() const
|
||||
{
|
||||
return item_type_;
|
||||
}
|
||||
|
||||
inline bool repeat() const
|
||||
{
|
||||
return repeat_;
|
||||
}
|
||||
|
||||
inline int64_t sampling_frequency() const
|
||||
{
|
||||
return sampling_frequency_;
|
||||
}
|
||||
|
||||
inline uint64_t samples() const
|
||||
{
|
||||
return samples_;
|
||||
}
|
||||
|
||||
private:
|
||||
gr::blocks::file_source::sptr file_source_;
|
||||
unpack_intspir_1bit_samples_sptr unpack_intspir_;
|
||||
gnss_shared_ptr<gr::block> valve_;
|
||||
gr::blocks::file_sink::sptr sink_;
|
||||
gr::blocks::throttle::sptr throttle_;
|
||||
std::string filename_;
|
||||
std::string item_type_;
|
||||
std::string dump_filename_;
|
||||
std::string role_;
|
||||
|
||||
uint64_t samples_;
|
||||
int64_t sampling_frequency_;
|
||||
size_t item_size_;
|
||||
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
|
||||
bool repeat_;
|
||||
bool dump_;
|
||||
|
||||
// Throttle control
|
||||
bool enable_throttle_control_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "spir_gss6450_file_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include <glog/logging.h>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
@ -25,9 +26,11 @@
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role, uint32_t in_streams, uint32_t out_streams, Concurrent_Queue<pmt::pmt_t>* queue) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
||||
const std::string& role, uint32_t in_streams, uint32_t out_streams, Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: SignalSourceBase(configuration, role, "Spir_GSS6450_File_Signal_Source"s), in_streams_(in_streams), out_streams_(out_streams)
|
||||
{
|
||||
const std::string default_filename("../data/my_capture.dat");
|
||||
const std::string default_dump_filename("../data/my_capture_dump.dat");
|
||||
|
@ -22,8 +22,8 @@
|
||||
#define GNSS_SDR_SPIR_GSS6450_FILE_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include "signal_source_base.h"
|
||||
#include "unpack_spir_gss6450_samples.h"
|
||||
#include <gnuradio/blocks/deinterleave.h>
|
||||
#include <gnuradio/blocks/endian_swap.h>
|
||||
@ -50,23 +50,12 @@ class ConfigurationInterface;
|
||||
* \brief Class that reads signals samples from a file
|
||||
* and adapts it to a SignalSourceInterface
|
||||
*/
|
||||
class SpirGSS6450FileSignalSource : public GNSSBlockInterface
|
||||
class SpirGSS6450FileSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
SpirGSS6450FileSignalSource(const ConfigurationInterface* configuration, const std::string& role,
|
||||
uint32_t in_streams, uint32_t out_streams, Concurrent_Queue<pmt::pmt_t>* queue);
|
||||
|
||||
~SpirGSS6450FileSignalSource() = default;
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Spir_GSS6450_File_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -114,7 +103,6 @@ private:
|
||||
std::vector<gr::blocks::throttle::sptr> throttle_vec_;
|
||||
std::string filename_;
|
||||
std::string dump_filename_;
|
||||
std::string role_;
|
||||
std::string item_type_;
|
||||
uint64_t samples_;
|
||||
int64_t sampling_frequency_;
|
||||
|
@ -9,296 +9,77 @@
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "two_bit_cpx_file_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include <glog/logging.h>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
|
||||
TwoBitCpxFileSignalSource::TwoBitCpxFileSignalSource(
|
||||
const ConfigurationInterface* configuration,
|
||||
const std::string& role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue) : role_(role),
|
||||
in_streams_(in_streams),
|
||||
out_streams_(out_streams)
|
||||
unsigned int in_streams, unsigned int out_streams,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: FileSourceBase(configuration, role, "Two_Bit_Cpx_File_Signal_Source"s, queue, "byte"s)
|
||||
{
|
||||
const std::string default_filename("../data/my_capture.dat");
|
||||
const std::string default_item_type("byte");
|
||||
const std::string default_dump_filename("../data/my_capture_dump.dat");
|
||||
|
||||
samples_ = configuration->property(role + ".samples", static_cast<uint64_t>(0));
|
||||
sampling_frequency_ = configuration->property(role + ".sampling_frequency", static_cast<int64_t>(0));
|
||||
filename_ = configuration->property(role + ".filename", default_filename);
|
||||
|
||||
// override value with commandline flag, if present
|
||||
if (FLAGS_signal_source != "-")
|
||||
{
|
||||
filename_ = FLAGS_signal_source;
|
||||
}
|
||||
if (FLAGS_s != "-")
|
||||
{
|
||||
filename_ = FLAGS_s;
|
||||
}
|
||||
|
||||
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
||||
repeat_ = configuration->property(role + ".repeat", false);
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false);
|
||||
|
||||
if (item_type_ == "byte")
|
||||
{
|
||||
item_size_ = sizeof(char);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_ << " unrecognized item type. Using byte.";
|
||||
item_size_ = sizeof(char);
|
||||
}
|
||||
try
|
||||
{
|
||||
file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_);
|
||||
unpack_byte_ = make_unpack_byte_2bit_cpx_samples();
|
||||
inter_shorts_to_cpx_ = gr::blocks::interleaved_short_to_complex::make(false, true); // I/Q swap enabled
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr
|
||||
<< "The receiver was configured to work with a file signal source\n"
|
||||
<< "but the specified file is unreachable by GNSS-SDR.\n"
|
||||
<< "Please modify your configuration file\n"
|
||||
<< "and point SignalSource.filename to a valid raw data file. Then:\n"
|
||||
<< "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf\n"
|
||||
<< "Examples of configuration files available at:\n"
|
||||
<< GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/\n";
|
||||
|
||||
LOG(WARNING) << "file_signal_source: Unable to open the samples file "
|
||||
<< filename_.c_str() << ", exiting the program.";
|
||||
throw(e);
|
||||
}
|
||||
|
||||
DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")";
|
||||
|
||||
if (samples_ == 0) // read all file
|
||||
{
|
||||
/*!
|
||||
* BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File.
|
||||
* A possible solution is to compute the file length in samples using file size, excluding the last 2 milliseconds, and enable always the
|
||||
* valve block
|
||||
*/
|
||||
std::ifstream file(filename_.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
|
||||
std::ifstream::pos_type size;
|
||||
|
||||
if (file.is_open())
|
||||
{
|
||||
size = file.tellg();
|
||||
LOG(INFO) << "Total samples in the file= " << floor(static_cast<double>(size) / static_cast<double>(item_size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "file_signal_source: Unable to open the samples file " << filename_.c_str() << '\n';
|
||||
LOG(ERROR) << "file_signal_source: Unable to open the samples file " << filename_.c_str();
|
||||
}
|
||||
std::streamsize ss = std::cout.precision();
|
||||
std::cout << std::setprecision(16);
|
||||
std::cout << "Processing file " << filename_ << ", which contains " << size << " [bytes]\n";
|
||||
std::cout.precision(ss);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
int sample_packet_factor = 2; // 1 byte -> 2 samples
|
||||
samples_ = floor(static_cast<double>(size) / static_cast<double>(item_size())) * sample_packet_factor;
|
||||
samples_ = samples_ - ceil(0.002 * static_cast<double>(sampling_frequency_)); // process all the samples available in the file excluding the last 2 ms
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(samples_ > 0) << "File does not contain enough samples to process.";
|
||||
const double signal_duration_s = static_cast<double>(samples_) * (1 / static_cast<double>(sampling_frequency_));
|
||||
LOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
|
||||
std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n";
|
||||
|
||||
valve_ = gnss_sdr_make_valve(sizeof(gr_complex), samples_, queue);
|
||||
DLOG(INFO) << "valve(" << valve_->unique_id() << ")";
|
||||
|
||||
if (dump_)
|
||||
{
|
||||
// sink_ = gr_make_file_sink(item_size_, dump_filename_.c_str());
|
||||
sink_ = gr::blocks::file_sink::make(sizeof(gr_complex), dump_filename_.c_str());
|
||||
DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")";
|
||||
}
|
||||
|
||||
if (enable_throttle_control_)
|
||||
{
|
||||
throttle_ = gr::blocks::throttle::make(sizeof(gr_complex), sampling_frequency_);
|
||||
}
|
||||
DLOG(INFO) << "File source filename " << filename_;
|
||||
DLOG(INFO) << "Samples " << samples_;
|
||||
DLOG(INFO) << "Sampling frequency " << sampling_frequency_;
|
||||
DLOG(INFO) << "Item type " << item_type_;
|
||||
DLOG(INFO) << "Item size " << item_size_;
|
||||
DLOG(INFO) << "Repeat " << repeat_;
|
||||
DLOG(INFO) << "Dump " << dump_;
|
||||
DLOG(INFO) << "Dump filename " << dump_filename_;
|
||||
if (in_streams_ > 0)
|
||||
if (in_streams > 0)
|
||||
{
|
||||
LOG(ERROR) << "A signal source does not have an input stream";
|
||||
}
|
||||
if (out_streams_ > 1)
|
||||
if (out_streams > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one output stream";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TwoBitCpxFileSignalSource::connect(gr::top_block_sptr top_block)
|
||||
std::tuple<size_t, bool> TwoBitCpxFileSignalSource::itemTypeToSize()
|
||||
{
|
||||
if (samples_ > 0)
|
||||
auto is_complex = false;
|
||||
auto item_size = size_t(sizeof(char)); // default
|
||||
|
||||
if (item_type() == "byte")
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->connect(file_source_, 0, unpack_byte_, 0);
|
||||
top_block->connect(unpack_byte_, 0, inter_shorts_to_cpx_, 0);
|
||||
top_block->connect(inter_shorts_to_cpx_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "connected file source to throttle";
|
||||
top_block->connect(throttle_, 0, valve_, 0);
|
||||
DLOG(INFO) << "connected throttle to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected valve to file sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
top_block->connect(file_source_, 0, unpack_byte_, 0);
|
||||
top_block->connect(unpack_byte_, 0, inter_shorts_to_cpx_, 0);
|
||||
top_block->connect(inter_shorts_to_cpx_, 0, valve_, 0);
|
||||
DLOG(INFO) << "connected file source to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected valve to file sink";
|
||||
}
|
||||
}
|
||||
item_size = sizeof(char);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->connect(file_source_, 0, unpack_byte_, 0);
|
||||
top_block->connect(unpack_byte_, 0, inter_shorts_to_cpx_, 0);
|
||||
top_block->connect(inter_shorts_to_cpx_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "connected file source to throttle";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(throttle_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected file source to sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(file_source_, 0, unpack_byte_, 0);
|
||||
top_block->connect(unpack_byte_, 0, inter_shorts_to_cpx_, 0);
|
||||
top_block->connect(inter_shorts_to_cpx_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected file source to sink";
|
||||
}
|
||||
}
|
||||
LOG(WARNING) << item_type() << " unrecognized item type. Using byte.";
|
||||
}
|
||||
|
||||
return std::make_tuple(item_size, is_complex);
|
||||
}
|
||||
|
||||
// 1 byte -> 2 samples
|
||||
double TwoBitCpxFileSignalSource::packetsPerSample() const { return 2.0; }
|
||||
gnss_shared_ptr<gr::block> TwoBitCpxFileSignalSource::source() const { return inter_shorts_to_cpx_; }
|
||||
|
||||
void TwoBitCpxFileSignalSource::disconnect(gr::top_block_sptr top_block)
|
||||
|
||||
void TwoBitCpxFileSignalSource::create_file_source_hook()
|
||||
{
|
||||
if (samples_ > 0)
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, unpack_byte_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack_byte_";
|
||||
top_block->connect(unpack_byte_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "disconnected unpack_byte_ to throttle_";
|
||||
top_block->disconnect(throttle_, 0, valve_, 0);
|
||||
DLOG(INFO) << "disconnected throttle to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected valve to file sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, unpack_byte_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack_byte_";
|
||||
top_block->disconnect(unpack_byte_, 0, valve_, 0);
|
||||
DLOG(INFO) << "disconnected unpack_byte_ to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected valve to file sink";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, unpack_byte_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack_byte_";
|
||||
top_block->disconnect(unpack_byte_, 0, throttle_, 0);
|
||||
DLOG(INFO) << "disconnected unpack_byte_ to throttle";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(unpack_byte_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected funpack_byte_ to sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(file_source_, 0, unpack_byte_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack_byte_";
|
||||
top_block->disconnect(unpack_byte_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected unpack_byte_ to sink";
|
||||
}
|
||||
}
|
||||
}
|
||||
unpack_byte_ = make_unpack_byte_2bit_cpx_samples();
|
||||
DLOG(INFO) << "unpack_byte_2bit_cpx_samples(" << unpack_byte_->unique_id() << ")";
|
||||
inter_shorts_to_cpx_ = gr::blocks::interleaved_short_to_complex::make(false, true); // I/Q swap enabled
|
||||
DLOG(INFO) << "interleaved_short_to_complex(" << inter_shorts_to_cpx_->unique_id() << ")";
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr TwoBitCpxFileSignalSource::get_left_block()
|
||||
void TwoBitCpxFileSignalSource::pre_connect_hook(gr::top_block_sptr top_block)
|
||||
{
|
||||
LOG(WARNING) << "Left block of a signal source should not be retrieved";
|
||||
// return gr_block_sptr();
|
||||
return gr::blocks::file_source::sptr();
|
||||
top_block->connect(file_source(), 0, unpack_byte_, 0);
|
||||
top_block->connect(unpack_byte_, 0, inter_shorts_to_cpx_, 0);
|
||||
DLOG(INFO) << "connected file_source to unpacker";
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr TwoBitCpxFileSignalSource::get_right_block()
|
||||
void TwoBitCpxFileSignalSource::pre_disconnect_hook(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (samples_ > 0)
|
||||
{
|
||||
return valve_;
|
||||
}
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
return throttle_;
|
||||
}
|
||||
return unpack_byte_;
|
||||
top_block->disconnect(file_source(), 0, unpack_byte_, 0);
|
||||
top_block->disconnect(unpack_byte_, 0, inter_shorts_to_cpx_, 0);
|
||||
DLOG(INFO) << "disconnected file_source from unpacker";
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
@ -20,17 +20,9 @@
|
||||
#ifndef GNSS_SDR_TWO_BIT_CPX_FILE_SIGNAL_SOURCE_H
|
||||
#define GNSS_SDR_TWO_BIT_CPX_FILE_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "file_source_base.h"
|
||||
#include "unpack_byte_2bit_cpx_samples.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/interleaved_short_to_complex.h>
|
||||
#include <gnuradio/blocks/throttle.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
#include <pmt/pmt.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
* \{ */
|
||||
@ -44,7 +36,7 @@ class ConfigurationInterface;
|
||||
* \brief Class that reads signals samples from a file
|
||||
* and adapts it to a SignalSourceInterface
|
||||
*/
|
||||
class TwoBitCpxFileSignalSource : public GNSSBlockInterface
|
||||
class TwoBitCpxFileSignalSource : public FileSourceBase
|
||||
{
|
||||
public:
|
||||
TwoBitCpxFileSignalSource(const ConfigurationInterface* configuration,
|
||||
@ -54,74 +46,18 @@ public:
|
||||
Concurrent_Queue<pmt::pmt_t>* queue);
|
||||
|
||||
~TwoBitCpxFileSignalSource() = default;
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Two_Bit_Cpx_File_Signal_Source".
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Two_Bit_Cpx_File_Signal_Source";
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
inline std::string filename() const
|
||||
{
|
||||
return filename_;
|
||||
}
|
||||
|
||||
inline std::string item_type() const
|
||||
{
|
||||
return item_type_;
|
||||
}
|
||||
|
||||
inline bool repeat() const
|
||||
{
|
||||
return repeat_;
|
||||
}
|
||||
|
||||
inline int64_t sampling_frequency() const
|
||||
{
|
||||
return sampling_frequency_;
|
||||
}
|
||||
|
||||
inline uint64_t samples() const
|
||||
{
|
||||
return samples_;
|
||||
}
|
||||
protected:
|
||||
std::tuple<size_t, bool> itemTypeToSize() override;
|
||||
double packetsPerSample() const override;
|
||||
gnss_shared_ptr<gr::block> source() const override;
|
||||
void create_file_source_hook() override;
|
||||
void pre_connect_hook(gr::top_block_sptr top_block) override;
|
||||
void pre_disconnect_hook(gr::top_block_sptr top_block) override;
|
||||
|
||||
private:
|
||||
gr::blocks::file_source::sptr file_source_;
|
||||
gr::blocks::interleaved_short_to_complex::sptr inter_shorts_to_cpx_;
|
||||
unpack_byte_2bit_cpx_samples_sptr unpack_byte_;
|
||||
gnss_shared_ptr<gr::block> valve_;
|
||||
gr::blocks::file_sink::sptr sink_;
|
||||
gr::blocks::throttle::sptr throttle_;
|
||||
std::string filename_;
|
||||
std::string item_type_;
|
||||
std::string dump_filename_;
|
||||
std::string role_;
|
||||
size_t item_size_;
|
||||
uint64_t samples_;
|
||||
int64_t sampling_frequency_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
bool repeat_;
|
||||
bool dump_;
|
||||
// Throttle control
|
||||
bool enable_throttle_control_;
|
||||
gr::blocks::interleaved_short_to_complex::sptr inter_shorts_to_cpx_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
@ -18,291 +18,122 @@
|
||||
|
||||
#include "two_bit_packed_file_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/blocks/char_to_float.h>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
TwoBitPackedFileSignalSource::TwoBitPackedFileSignalSource(
|
||||
const ConfigurationInterface* configuration,
|
||||
const std::string& role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue) : role_(role),
|
||||
in_streams_(in_streams),
|
||||
out_streams_(out_streams)
|
||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: FileSourceBase(configuration, role, "Two_Bit_Packed_File_Signal_Source"s, queue, "byte"s), sample_type_(configuration->property(role + ".sample_type", "real"s)), // options: "real", "iq", "qi"
|
||||
big_endian_items_(configuration->property(role + ".big_endian_items", true)),
|
||||
big_endian_bytes_(configuration->property(role + ".big_endian_bytes", false)),
|
||||
reverse_interleaving_(false)
|
||||
{
|
||||
const std::string default_filename("../data/my_capture.dat");
|
||||
const std::string default_item_type("byte");
|
||||
const std::string default_dump_filename("../data/my_capture_dump.dat");
|
||||
const std::string default_sample_type("real");
|
||||
const double default_seconds_to_skip = 0.0;
|
||||
|
||||
samples_ = configuration->property(role + ".samples", static_cast<uint64_t>(0));
|
||||
sampling_frequency_ = configuration->property(role + ".sampling_frequency", static_cast<int64_t>(0));
|
||||
filename_ = configuration->property(role + ".filename", default_filename);
|
||||
|
||||
// override value with commandline flag, if present
|
||||
if (FLAGS_signal_source != "-")
|
||||
{
|
||||
filename_ = FLAGS_signal_source;
|
||||
}
|
||||
if (FLAGS_s != "-")
|
||||
{
|
||||
filename_ = FLAGS_s;
|
||||
}
|
||||
|
||||
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
||||
big_endian_items_ = configuration->property(role + ".big_endian_items", true);
|
||||
big_endian_bytes_ = configuration->property(role + ".big_endian_bytes", false);
|
||||
sample_type_ = configuration->property(role + ".sample_type", default_sample_type); // options: "real", "iq", "qi"
|
||||
repeat_ = configuration->property(role + ".repeat", false);
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false);
|
||||
const double seconds_to_skip = configuration->property(role + ".seconds_to_skip", default_seconds_to_skip);
|
||||
int64_t bytes_to_skip = 0;
|
||||
|
||||
if (item_type_ == "byte")
|
||||
{
|
||||
item_size_ = sizeof(char);
|
||||
}
|
||||
else if (item_type_ == "short")
|
||||
{
|
||||
// If we have shorts stored in little endian format, might as
|
||||
// well read them in as bytes.
|
||||
if (big_endian_items_)
|
||||
{
|
||||
item_size_ = sizeof(int16_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
item_size_ = sizeof(char);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_ << " unrecognized item type. Using byte.";
|
||||
item_size_ = sizeof(char);
|
||||
}
|
||||
|
||||
reverse_interleaving_ = false;
|
||||
is_complex_ = true;
|
||||
if (sample_type_ == "real")
|
||||
{
|
||||
is_complex_ = false;
|
||||
}
|
||||
else if (sample_type_ == "iq")
|
||||
{
|
||||
is_complex_ = true;
|
||||
}
|
||||
else if (sample_type_ == "qi")
|
||||
{
|
||||
is_complex_ = true;
|
||||
reverse_interleaving_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << sample_type_ << " unrecognized sample type. Assuming: "
|
||||
<< (is_complex_ ? (reverse_interleaving_ ? "qi" : "iq") : "real");
|
||||
}
|
||||
try
|
||||
{
|
||||
file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_);
|
||||
|
||||
if (seconds_to_skip > 0)
|
||||
{
|
||||
bytes_to_skip = static_cast<int64_t>(
|
||||
seconds_to_skip * sampling_frequency_ / 4);
|
||||
if (is_complex_)
|
||||
{
|
||||
bytes_to_skip <<= 1;
|
||||
}
|
||||
file_source_->seek(bytes_to_skip, SEEK_SET);
|
||||
}
|
||||
|
||||
unpack_samples_ = make_unpack_2bit_samples(big_endian_bytes_,
|
||||
item_size_, big_endian_items_, reverse_interleaving_);
|
||||
if (is_complex_)
|
||||
{
|
||||
char_to_float_ =
|
||||
gr::blocks::interleaved_char_to_complex::make(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
char_to_float_ =
|
||||
gr::blocks::char_to_float::make();
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr
|
||||
<< "The receiver was configured to work with a file signal source\n"
|
||||
<< "but the specified file is unreachable by GNSS-SDR.\n"
|
||||
<< "Please modify your configuration file\n"
|
||||
<< "and point SignalSource.filename to a valid raw data file. Then:\n"
|
||||
<< "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf\n"
|
||||
<< "Examples of configuration files available at:\n"
|
||||
<< GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/\n";
|
||||
|
||||
LOG(WARNING) << "file_signal_source: Unable to open the samples file "
|
||||
<< filename_.c_str() << ", exiting the program.";
|
||||
throw(e);
|
||||
}
|
||||
|
||||
DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")";
|
||||
|
||||
const size_t output_item_size = (is_complex_ ? sizeof(gr_complex) : sizeof(float));
|
||||
|
||||
if (samples_ == 0) // read all file
|
||||
{
|
||||
/*!
|
||||
* BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File.
|
||||
* A possible solution is to compute the file length in samples using file size, excluding the last 2 milliseconds, and enable always the
|
||||
* valve block
|
||||
*/
|
||||
std::ifstream file(filename_.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
|
||||
std::ifstream::pos_type size;
|
||||
|
||||
if (file.is_open())
|
||||
{
|
||||
size = file.tellg();
|
||||
samples_ = floor(static_cast<double>(size) * (is_complex_ ? 2.0 : 4.0));
|
||||
LOG(INFO) << "Total samples in the file= " << samples_; // 4 samples per byte
|
||||
samples_ -= bytes_to_skip;
|
||||
|
||||
// Also skip the last two milliseconds:
|
||||
samples_ -= ceil(0.002 * sampling_frequency_ / (is_complex_ ? 2.0 : 4.0));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "file_signal_source: Unable to open the samples file " << filename_.c_str() << '\n';
|
||||
LOG(ERROR) << "file_signal_source: Unable to open the samples file " << filename_.c_str();
|
||||
}
|
||||
std::streamsize ss = std::cout.precision();
|
||||
std::cout << std::setprecision(16);
|
||||
std::cout << "Processing file " << filename_ << ", which contains " << size << " [bytes]\n";
|
||||
std::cout.precision(ss);
|
||||
}
|
||||
|
||||
CHECK(samples_ > 0) << "File does not contain enough samples to process.";
|
||||
double signal_duration_s;
|
||||
signal_duration_s = static_cast<double>(samples_) * (1 / static_cast<double>(sampling_frequency_));
|
||||
LOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
|
||||
std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n";
|
||||
|
||||
valve_ = gnss_sdr_make_valve(output_item_size, samples_, queue);
|
||||
DLOG(INFO) << "valve(" << valve_->unique_id() << ")";
|
||||
|
||||
if (dump_)
|
||||
{
|
||||
// sink_ = gr_make_file_sink(item_size_, dump_filename_.c_str());
|
||||
sink_ = gr::blocks::file_sink::make(output_item_size, dump_filename_.c_str());
|
||||
DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")";
|
||||
}
|
||||
|
||||
if (enable_throttle_control_)
|
||||
{
|
||||
throttle_ = gr::blocks::throttle::make(output_item_size, sampling_frequency_);
|
||||
}
|
||||
DLOG(INFO) << "File source filename " << filename_;
|
||||
DLOG(INFO) << "Samples " << samples_;
|
||||
DLOG(INFO) << "Sampling frequency " << sampling_frequency_;
|
||||
DLOG(INFO) << "Item type " << item_type_;
|
||||
DLOG(INFO) << "Item size " << item_size_;
|
||||
DLOG(INFO) << "Repeat " << repeat_;
|
||||
DLOG(INFO) << "Dump " << dump_;
|
||||
DLOG(INFO) << "Dump filename " << dump_filename_;
|
||||
if (in_streams_ > 0)
|
||||
if (in_streams > 0)
|
||||
{
|
||||
LOG(ERROR) << "A signal source does not have an input stream";
|
||||
}
|
||||
if (out_streams_ > 1)
|
||||
if (out_streams > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one output stream";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TwoBitPackedFileSignalSource::connect(gr::top_block_sptr top_block)
|
||||
std::tuple<size_t, bool> TwoBitPackedFileSignalSource::itemTypeToSize()
|
||||
{
|
||||
gr::basic_block_sptr left_block = file_source_;
|
||||
gr::basic_block_sptr right_block = unpack_samples_;
|
||||
auto is_complex_t = false;
|
||||
auto item_size = size_t(sizeof(char)); // default
|
||||
|
||||
top_block->connect(file_source_, 0, unpack_samples_, 0);
|
||||
left_block = right_block;
|
||||
if (item_type() == "byte")
|
||||
{
|
||||
item_size = sizeof(char);
|
||||
}
|
||||
else if (item_type() == "short")
|
||||
{
|
||||
// If we have shorts stored in little endian format, might as
|
||||
// well read them in as bytes.
|
||||
// TODO: this seems to make assumptions about the endianness of this machine
|
||||
if (big_endian_items_)
|
||||
{
|
||||
item_size = sizeof(int16_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
// how can this be right? the number of samples is computed based on this value
|
||||
item_size = sizeof(char);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type() << " unrecognized item type. Using byte.";
|
||||
}
|
||||
|
||||
// the complex-ness of the input is inferred from the output type
|
||||
if (sample_type_ == "real")
|
||||
{
|
||||
is_complex_t = false;
|
||||
}
|
||||
else if (sample_type_ == "iq")
|
||||
{
|
||||
is_complex_t = true;
|
||||
}
|
||||
else if (sample_type_ == "qi")
|
||||
{
|
||||
is_complex_t = true;
|
||||
reverse_interleaving_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << sample_type_ << " unrecognized sample type. Assuming: "
|
||||
<< (is_complex_t ? (reverse_interleaving_ ? "qi" : "iq") : "real");
|
||||
}
|
||||
|
||||
|
||||
return std::make_tuple(item_size, is_complex_t);
|
||||
}
|
||||
|
||||
// Each sample is 2 bits; if the item_type() is char, then the size is 8/2 = 4 packets per sample
|
||||
// If the item_type() is short, then the size is 16/2 = 8 packets per sample
|
||||
double TwoBitPackedFileSignalSource::packetsPerSample() const { return item_size() / 2.0; }
|
||||
gnss_shared_ptr<gr::block> TwoBitPackedFileSignalSource::source() const { return char_to_float_; }
|
||||
|
||||
void TwoBitPackedFileSignalSource::create_file_source_hook()
|
||||
{
|
||||
unpack_samples_ = make_unpack_2bit_samples(big_endian_bytes_, item_size(),
|
||||
big_endian_items_, reverse_interleaving_);
|
||||
DLOG(INFO) << "unpack_byte_2bit_samples(" << unpack_samples_->unique_id() << ")";
|
||||
|
||||
if (is_complex())
|
||||
{
|
||||
char_to_float_ = gr::blocks::interleaved_char_to_complex::make(false);
|
||||
DLOG(INFO) << "interleaved_char_to_complex(" << char_to_float_->unique_id() << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
char_to_float_ = gr::blocks::char_to_float::make();
|
||||
DLOG(INFO) << "char_to_float(" << char_to_float_->unique_id() << ")";
|
||||
}
|
||||
}
|
||||
|
||||
void TwoBitPackedFileSignalSource::pre_connect_hook(gr::top_block_sptr top_block)
|
||||
{
|
||||
top_block->connect(file_source(), 0, unpack_samples_, 0);
|
||||
DLOG(INFO) << "connected file source to unpack samples";
|
||||
right_block = char_to_float_;
|
||||
top_block->connect(left_block, 0, right_block, 0);
|
||||
left_block = right_block;
|
||||
top_block->connect(unpack_samples_, 0, char_to_float_, 0);
|
||||
DLOG(INFO) << "connected unpack samples to char to float";
|
||||
|
||||
if (enable_throttle_control_)
|
||||
{
|
||||
right_block = throttle_;
|
||||
top_block->connect(left_block, 0, right_block, 0);
|
||||
left_block = right_block;
|
||||
DLOG(INFO) << " connected to throttle";
|
||||
}
|
||||
|
||||
top_block->connect(left_block, 0, valve_, 0);
|
||||
DLOG(INFO) << "connected to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "connected valve to file sink";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TwoBitPackedFileSignalSource::disconnect(gr::top_block_sptr top_block)
|
||||
void TwoBitPackedFileSignalSource::pre_disconnect_hook(gr::top_block_sptr top_block)
|
||||
{
|
||||
gr::basic_block_sptr left_block = file_source_;
|
||||
gr::basic_block_sptr right_block = unpack_samples_;
|
||||
|
||||
top_block->disconnect(file_source_, 0, unpack_samples_, 0);
|
||||
left_block = right_block;
|
||||
|
||||
top_block->disconnect(file_source(), 0, unpack_samples_, 0);
|
||||
DLOG(INFO) << "disconnected file source to unpack samples";
|
||||
right_block = char_to_float_;
|
||||
top_block->disconnect(left_block, 0, right_block, 0);
|
||||
left_block = right_block;
|
||||
top_block->disconnect(unpack_samples_, 0, char_to_float_, 0);
|
||||
DLOG(INFO) << "disconnected unpack samples to char to float";
|
||||
|
||||
if (enable_throttle_control_)
|
||||
{
|
||||
right_block = throttle_;
|
||||
top_block->disconnect(left_block, 0, right_block, 0);
|
||||
left_block = right_block;
|
||||
DLOG(INFO) << " disconnected to throttle";
|
||||
}
|
||||
|
||||
top_block->disconnect(left_block, 0, valve_, 0);
|
||||
DLOG(INFO) << "disconnected to valve";
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(valve_, 0, sink_, 0);
|
||||
DLOG(INFO) << "disconnected valve to file sink";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr TwoBitPackedFileSignalSource::get_left_block()
|
||||
{
|
||||
LOG(WARNING) << "Left block of a signal source should not be retrieved";
|
||||
// return gr_block_sptr();
|
||||
return gr::blocks::file_source::sptr();
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr TwoBitPackedFileSignalSource::get_right_block()
|
||||
{
|
||||
return valve_;
|
||||
}
|
||||
|
@ -21,17 +21,9 @@
|
||||
#ifndef GNSS_SDR_TWO_BIT_PACKED_FILE_SIGNAL_SOURCE_H
|
||||
#define GNSS_SDR_TWO_BIT_PACKED_FILE_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "file_source_base.h"
|
||||
#include "unpack_2bit_samples.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/interleaved_char_to_complex.h>
|
||||
#include <gnuradio/blocks/throttle.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
#include <pmt/pmt.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
@ -46,7 +38,7 @@ class ConfigurationInterface;
|
||||
* \brief Class that reads signals samples from a file
|
||||
* and adapts it to a SignalSourceInterface
|
||||
*/
|
||||
class TwoBitPackedFileSignalSource : public GNSSBlockInterface
|
||||
class TwoBitPackedFileSignalSource : public FileSourceBase
|
||||
{
|
||||
public:
|
||||
TwoBitPackedFileSignalSource(const ConfigurationInterface* configuration, const std::string& role,
|
||||
@ -54,54 +46,8 @@ public:
|
||||
Concurrent_Queue<pmt::pmt_t>* queue);
|
||||
|
||||
~TwoBitPackedFileSignalSource() = default;
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Two_Bit_Packed_File_Signal_Source".
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Two_Bit_Packed_File_Signal_Source";
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
inline std::string filename() const
|
||||
{
|
||||
return filename_;
|
||||
}
|
||||
|
||||
inline std::string item_type() const
|
||||
{
|
||||
return item_type_;
|
||||
}
|
||||
|
||||
inline bool repeat() const
|
||||
{
|
||||
return repeat_;
|
||||
}
|
||||
|
||||
inline int64_t sampling_frequency() const
|
||||
{
|
||||
return sampling_frequency_;
|
||||
}
|
||||
|
||||
inline uint64_t samples() const
|
||||
{
|
||||
return samples_;
|
||||
}
|
||||
|
||||
private:
|
||||
inline bool big_endian_items() const
|
||||
{
|
||||
return big_endian_items_;
|
||||
@ -112,41 +58,27 @@ public:
|
||||
return big_endian_bytes_;
|
||||
}
|
||||
|
||||
inline bool is_complex() const
|
||||
{
|
||||
return is_complex_;
|
||||
}
|
||||
|
||||
inline bool reverse_interleaving() const
|
||||
{
|
||||
return reverse_interleaving_;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::tuple<size_t, bool> itemTypeToSize() override;
|
||||
double packetsPerSample() const override;
|
||||
gnss_shared_ptr<gr::block> source() const override;
|
||||
void create_file_source_hook() override;
|
||||
void pre_connect_hook(gr::top_block_sptr top_block) override;
|
||||
void pre_disconnect_hook(gr::top_block_sptr top_block) override;
|
||||
|
||||
private:
|
||||
gr::blocks::file_source::sptr file_source_;
|
||||
unpack_2bit_samples_sptr unpack_samples_;
|
||||
gr::basic_block_sptr char_to_float_;
|
||||
gnss_shared_ptr<gr::block> valve_;
|
||||
gr::blocks::file_sink::sptr sink_;
|
||||
gr::blocks::throttle::sptr throttle_;
|
||||
std::string filename_;
|
||||
std::string item_type_;
|
||||
std::string dump_filename_;
|
||||
std::string role_;
|
||||
std::string sample_type_;
|
||||
uint64_t samples_;
|
||||
int64_t sampling_frequency_;
|
||||
size_t item_size_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
bool big_endian_items_;
|
||||
bool big_endian_bytes_;
|
||||
bool is_complex_;
|
||||
bool reverse_interleaving_;
|
||||
bool repeat_;
|
||||
bool dump_;
|
||||
// Throttle control
|
||||
bool enable_throttle_control_;
|
||||
unpack_2bit_samples_sptr unpack_samples_;
|
||||
gnss_shared_ptr<gr::block> char_to_float_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "uhd_signal_source.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include <glog/logging.h>
|
||||
#include <uhd/exception.hpp>
|
||||
@ -25,10 +26,13 @@
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
|
||||
UhdSignalSource::UhdSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role, unsigned int in_stream, unsigned int out_stream,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue) : role_(role), in_stream_(in_stream), out_stream_(out_stream)
|
||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: SignalSourceBase(configuration, role, "UHD_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
|
||||
{
|
||||
// DUMP PARAMETERS
|
||||
const std::string empty;
|
||||
|
@ -18,7 +18,7 @@
|
||||
#define GNSS_SDR_UHD_SIGNAL_SOURCE_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
#include <gnuradio/uhd/usrp_source.h>
|
||||
@ -38,7 +38,7 @@ class ConfigurationInterface;
|
||||
/*!
|
||||
* \brief This class reads samples from a UHD device (see http://code.ettus.com/redmine/ettus/projects/uhd/wiki)
|
||||
*/
|
||||
class UhdSignalSource : public GNSSBlockInterface
|
||||
class UhdSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
UhdSignalSource(const ConfigurationInterface* configuration,
|
||||
@ -47,19 +47,6 @@ public:
|
||||
|
||||
~UhdSignalSource() = default;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "UHD_Signal_Source"
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "UHD_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -89,7 +76,6 @@ private:
|
||||
std::string item_type_;
|
||||
std::string subdevice_;
|
||||
std::string clock_source_;
|
||||
std::string role_;
|
||||
|
||||
double sample_rate_;
|
||||
size_t item_size_;
|
||||
|
@ -17,6 +17,8 @@ if(ENABLE_FPGA OR ENABLE_AD9361)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_switch.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_dynamic_bit_selection.cc)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dynamic_bit_selection.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_buffer_monitor.cc)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_buffer_monitor.h)
|
||||
endif()
|
||||
|
||||
set(SIGNAL_SOURCE_LIB_SOURCES
|
||||
@ -90,6 +92,13 @@ if(ENABLE_FMCOMMS2 OR ENABLE_AD9361)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_FPGA OR ENABLE_AD9361)
|
||||
target_link_libraries(signal_source_libs
|
||||
PUBLIC
|
||||
algorithms_libs
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_CLANG_TIDY)
|
||||
if(CLANG_TIDY_EXE)
|
||||
set_target_properties(signal_source_libs
|
||||
|
259
src/algorithms/signal_source/libs/fpga_buffer_monitor.cc
Normal file
259
src/algorithms/signal_source/libs/fpga_buffer_monitor.cc
Normal file
@ -0,0 +1,259 @@
|
||||
/*!
|
||||
* \file fpga_buffer_monitor.cc
|
||||
* \brief Check receiver buffer overflow and monitor the status of the receiver
|
||||
* buffers.
|
||||
* \authors
|
||||
* <ul>
|
||||
* <li> Marc Majoral, 2021. mmajoral(at)cttc.es
|
||||
* </ul>
|
||||
*
|
||||
* Class that checks the receiver buffer overflow flags and monitors the status
|
||||
* of the receiver buffers.
|
||||
*
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "fpga_buffer_monitor.h"
|
||||
#include "command_event.h"
|
||||
#include "gnss_sdr_create_directory.h"
|
||||
#include "gnss_sdr_filesystem.h"
|
||||
#include <glog/logging.h>
|
||||
#include <ctime> // for time, localtime
|
||||
#include <fcntl.h> // for open, O_RDWR, O_SYNC
|
||||
#include <fstream> // for string, ofstream
|
||||
#include <iostream> // for cout
|
||||
#include <sys/mman.h> // for mmap
|
||||
#include <utility> // for move
|
||||
|
||||
|
||||
Fpga_buffer_monitor::Fpga_buffer_monitor(const std::string &device_name, uint32_t num_freq_bands, bool dump, std::string dump_filename)
|
||||
{
|
||||
d_num_freq_bands = num_freq_bands;
|
||||
d_dump = dump;
|
||||
d_dump_filename = std::move(dump_filename);
|
||||
|
||||
// open device descriptor
|
||||
if ((d_device_descriptor = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1)
|
||||
{
|
||||
LOG(WARNING) << "Cannot open deviceio" << device_name;
|
||||
}
|
||||
|
||||
// device memory map
|
||||
d_map_base = reinterpret_cast<volatile unsigned *>(mmap(nullptr, FPGA_PAGE_SIZE,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0));
|
||||
|
||||
if (d_map_base == reinterpret_cast<void *>(-1))
|
||||
{
|
||||
LOG(WARNING) << "Cannot map the FPGA buffer monitor module";
|
||||
std::cout << "Could not map the FPGA buffer monitor \n";
|
||||
}
|
||||
|
||||
// sanity check: check test register
|
||||
if (buffer_monitor_test_register() < 0)
|
||||
{
|
||||
LOG(WARNING) << "FPGA buffer monitor test register sanity check failed";
|
||||
std::cout << "FPGA buffer monitor test register sanity check failed\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(INFO) << "FPGA buffer monitor test register sanity check success !";
|
||||
}
|
||||
|
||||
DLOG(INFO) << "FPGA buffer monitor class created";
|
||||
|
||||
// initialize maximum buffer occupancy in case buffer monitoring is enabled
|
||||
d_max_buff_occ_freq_band_0 = 0;
|
||||
d_max_buff_occ_freq_band_1 = 0;
|
||||
|
||||
if (d_dump)
|
||||
{
|
||||
std::string dump_path;
|
||||
// Get path
|
||||
if (d_dump_filename.find_last_of('/') != std::string::npos)
|
||||
{
|
||||
const std::string dump_filename_ = d_dump_filename.substr(d_dump_filename.find_last_of('/') + 1);
|
||||
dump_path = d_dump_filename.substr(0, d_dump_filename.find_last_of('/'));
|
||||
d_dump_filename = dump_filename_;
|
||||
}
|
||||
else
|
||||
{
|
||||
dump_path = std::string(".");
|
||||
}
|
||||
if (d_dump_filename.empty())
|
||||
{
|
||||
d_dump_filename = "FPGA_buffer_monitor_dump";
|
||||
}
|
||||
// remove extension if any
|
||||
if (d_dump_filename.substr(1).find_last_of('.') != std::string::npos)
|
||||
{
|
||||
d_dump_filename = d_dump_filename.substr(0, d_dump_filename.find_last_of('.'));
|
||||
}
|
||||
d_dump_filename = dump_path + fs::path::preferred_separator + d_dump_filename;
|
||||
// create directory
|
||||
if (!gnss_sdr_create_directory(dump_path))
|
||||
{
|
||||
std::cerr << "GNSS-SDR cannot create dump file for the Buffer Monitor block. Wrong permissions?\n";
|
||||
d_dump = false;
|
||||
}
|
||||
|
||||
std::string dump_filename_ = d_dump_filename;
|
||||
dump_filename_.append(".dat");
|
||||
|
||||
if (!d_dump_file.is_open())
|
||||
{
|
||||
try
|
||||
{
|
||||
d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
d_dump_file.open(dump_filename_.c_str(), std::ios::out | std::ios::binary);
|
||||
LOG(INFO) << "FPGA buffer monitor dump enabled. Log file: " << dump_filename_.c_str();
|
||||
}
|
||||
catch (const std::ifstream::failure &e)
|
||||
{
|
||||
LOG(WARNING) << "Exception opening FPGA buffer monitor dump file " << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Fpga_buffer_monitor::~Fpga_buffer_monitor()
|
||||
{
|
||||
close_device();
|
||||
|
||||
if (d_dump)
|
||||
{
|
||||
if (d_dump_file.is_open())
|
||||
{
|
||||
try
|
||||
{
|
||||
d_dump_file.close();
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
LOG(WARNING) << "Exception in FPGA buffer monitor destructor: " << ex.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Fpga_buffer_monitor::check_buffer_overflow_and_monitor_buffer_status()
|
||||
{
|
||||
// check buffer overflow flags
|
||||
uint32_t buffer_overflow_status = d_map_base[overflow_flags_reg_addr];
|
||||
|
||||
if ((buffer_overflow_status & overflow_freq_band_0_bit_pos) != 0)
|
||||
{
|
||||
if (d_num_freq_bands > 1)
|
||||
{
|
||||
LOG(ERROR) << "FPGA Buffer overflow in frequency band 0";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(ERROR) << "FPGA Buffer overflow";
|
||||
}
|
||||
}
|
||||
|
||||
if (d_num_freq_bands > 1)
|
||||
{
|
||||
if ((buffer_overflow_status & overflow_freq_band_1_bit_pos) != 0)
|
||||
{
|
||||
LOG(ERROR) << "FPGA Buffer overflow in frequency band 1";
|
||||
}
|
||||
}
|
||||
|
||||
// buffer monitor
|
||||
if (d_dump == 1)
|
||||
{
|
||||
uint32_t current_buff_occ_freq_band_0 = d_map_base[current_buff_occ_freq_band_0_reg_addr] * num_sapmples_per_buffer_element;
|
||||
uint32_t temp_max_buff_occ_freq_band_0 = d_map_base[max_buff_occ_freq_band_0_reg_addr] * num_sapmples_per_buffer_element;
|
||||
if (temp_max_buff_occ_freq_band_0 > d_max_buff_occ_freq_band_0)
|
||||
{
|
||||
d_max_buff_occ_freq_band_0 = temp_max_buff_occ_freq_band_0;
|
||||
}
|
||||
|
||||
time_t rawtime;
|
||||
struct tm *timeinfo;
|
||||
char buff_time_ch[80];
|
||||
|
||||
time(&rawtime);
|
||||
timeinfo = localtime(&rawtime);
|
||||
|
||||
strftime(buff_time_ch, sizeof(buff_time_ch), "%d-%m-%Y %H:%M:%S", timeinfo);
|
||||
std::string buffer_time(buff_time_ch);
|
||||
d_dump_file << buffer_time << " ";
|
||||
|
||||
std::string buffer_txt;
|
||||
// current buffer occupancy frequency band 0 (number of samples)
|
||||
buffer_txt = std::to_string(current_buff_occ_freq_band_0);
|
||||
d_dump_file << buffer_txt << " ";
|
||||
// temporary maximum buffer occupancy frequency band 0 (number of samples)
|
||||
buffer_txt = std::to_string(temp_max_buff_occ_freq_band_0);
|
||||
d_dump_file << buffer_txt << " ";
|
||||
// maximum buffer occupancy frequency band 0 (number of samples)
|
||||
buffer_txt = std::to_string(d_max_buff_occ_freq_band_0);
|
||||
d_dump_file << buffer_txt;
|
||||
|
||||
if (d_num_freq_bands > 1)
|
||||
{
|
||||
d_dump_file << " ";
|
||||
uint32_t current_buff_occ_freq_band_1 = d_map_base[current_buff_occ_freq_band_1_reg_addr] * num_sapmples_per_buffer_element;
|
||||
uint32_t temp_max_buff_occ_freq_band_1 = d_map_base[max_buff_occ_freq_band_1_reg_addr] * num_sapmples_per_buffer_element;
|
||||
if (temp_max_buff_occ_freq_band_1 > d_max_buff_occ_freq_band_1)
|
||||
{
|
||||
d_max_buff_occ_freq_band_1 = temp_max_buff_occ_freq_band_1;
|
||||
}
|
||||
|
||||
// current buffer occupancy frequency band 1 (number of samples)
|
||||
buffer_txt = std::to_string(current_buff_occ_freq_band_1);
|
||||
d_dump_file << buffer_txt << " ";
|
||||
// temporary maximum buffer occupancy frequency band 1 (number of samples)
|
||||
buffer_txt = std::to_string(temp_max_buff_occ_freq_band_1);
|
||||
d_dump_file << buffer_txt << " ";
|
||||
// maximum buffer occupancy frequency band 1 (number of samples)
|
||||
buffer_txt = std::to_string(d_max_buff_occ_freq_band_1);
|
||||
d_dump_file << buffer_txt << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_dump_file << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32_t Fpga_buffer_monitor::buffer_monitor_test_register()
|
||||
{
|
||||
// write value to test register
|
||||
d_map_base[test_reg_addr] = test_register_writeval;
|
||||
// read value from test register
|
||||
uint32_t readval = d_map_base[test_reg_addr];
|
||||
|
||||
if (test_register_writeval != readval)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Fpga_buffer_monitor::close_device()
|
||||
{
|
||||
auto *aux = const_cast<unsigned *>(d_map_base);
|
||||
if (munmap(static_cast<void *>(aux), FPGA_PAGE_SIZE) == -1)
|
||||
{
|
||||
std::cout << "Failed to unmap memory uio\n";
|
||||
}
|
||||
|
||||
close(d_device_descriptor);
|
||||
}
|
101
src/algorithms/signal_source/libs/fpga_buffer_monitor.h
Normal file
101
src/algorithms/signal_source/libs/fpga_buffer_monitor.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*!
|
||||
* \file fpga_buffer_monitor.h
|
||||
* \brief Check receiver buffer overflow and monitor the status of the receiver
|
||||
* buffers.
|
||||
* \authors
|
||||
* <ul>
|
||||
* <li> Marc Majoral, 2021. mmajoral(at)cttc.es
|
||||
* </ul>
|
||||
*
|
||||
* Class that checks the receiver buffer overflow flags and monitors the status
|
||||
* of the receiver buffers.
|
||||
*
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_FPGA_BUFFER_MONITOR_H
|
||||
#define GNSS_SDR_FPGA_BUFFER_MONITOR_H
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include <pmt/pmt.h> // pmt
|
||||
#include <cstdint> // for int32_t
|
||||
#include <fstream> // for string, ofstream
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
* \{ */
|
||||
/** \addtogroup Signal_Source_libs
|
||||
* \{ */
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Class that checks the receiver buffer overflow flags and monitors the
|
||||
* status of the receiver buffers.
|
||||
*/
|
||||
class Fpga_buffer_monitor
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* \brief Constructor
|
||||
*/
|
||||
explicit Fpga_buffer_monitor(const std::string& device_name,
|
||||
uint32_t num_freq_bands,
|
||||
bool dump,
|
||||
std::string dump_filename);
|
||||
|
||||
/*!
|
||||
* \brief Destructor
|
||||
*/
|
||||
~Fpga_buffer_monitor();
|
||||
|
||||
/*!
|
||||
* \brief This function checks buffer overflow and monitors the FPGA buffer status
|
||||
*/
|
||||
void check_buffer_overflow_and_monitor_buffer_status();
|
||||
|
||||
private:
|
||||
static const size_t FPGA_PAGE_SIZE = 0x10000;
|
||||
static const uint32_t test_register_writeval = 0x55AA;
|
||||
static const uint32_t num_sapmples_per_buffer_element = 2;
|
||||
// write addresses
|
||||
static const uint32_t reset_overflow_flags_and_max_buff_size_reg_addr = 0;
|
||||
// read-write addresses
|
||||
static const uint32_t test_reg_addr = 7;
|
||||
// read addresses
|
||||
static const uint32_t current_buff_occ_freq_band_0_reg_addr = 0;
|
||||
static const uint32_t current_buff_occ_freq_band_1_reg_addr = 1;
|
||||
static const uint32_t max_buff_occ_freq_band_0_reg_addr = 2;
|
||||
static const uint32_t max_buff_occ_freq_band_1_reg_addr = 3;
|
||||
static const uint32_t overflow_flags_reg_addr = 4;
|
||||
// FPGA-related constants
|
||||
static const uint32_t overflow_freq_band_0_bit_pos = 1;
|
||||
static const uint32_t overflow_freq_band_1_bit_pos = 2;
|
||||
|
||||
int32_t buffer_monitor_test_register();
|
||||
void close_device();
|
||||
|
||||
volatile unsigned* d_map_base; // driver memory map corresponding to the FPGA buffer monitor
|
||||
int d_device_descriptor; // driver descriptor corresponding to the FPGA buffer monitor
|
||||
|
||||
uint32_t d_num_freq_bands;
|
||||
|
||||
uint32_t d_max_buff_occ_freq_band_0;
|
||||
uint32_t d_max_buff_occ_freq_band_1;
|
||||
|
||||
bool d_dump;
|
||||
std::string d_dump_filename;
|
||||
std::ofstream d_dump_file;
|
||||
};
|
||||
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GNSS_SDR_FPGA_BUFFER_MONITOR_H
|
@ -381,7 +381,7 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
|
||||
std::cout << TEXT_BLUE << "New Galileo E5b I/NAV message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << TEXT_RESET << '\n';
|
||||
}
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
d_delta_t = tmp_obj->A_0G_10 + tmp_obj->A_1G_10 * (static_cast<double>(d_TOW_at_current_symbol_ms) / 1000.0 - tmp_obj->t_0G_10 + 604800 * (std::fmod(static_cast<float>(d_inav_nav.get_Galileo_week() - tmp_obj->WN_0G_10), 64.0)));
|
||||
d_delta_t = tmp_obj->A_0G + tmp_obj->A_1G * (static_cast<double>(d_TOW_at_current_symbol_ms) / 1000.0 - tmp_obj->t_0G + 604800 * (std::fmod(static_cast<float>(d_inav_nav.get_Galileo_week() - tmp_obj->WN_0G), 64.0)));
|
||||
DLOG(INFO) << "delta_t=" << d_delta_t << "[s]";
|
||||
}
|
||||
if (d_inav_nav.have_new_almanac() == true)
|
||||
|
@ -411,7 +411,7 @@ int glonass_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribu
|
||||
|
||||
// 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 + d_nav.A_1G * (d_TOW_at_current_symbol - d_nav.t_0G + 604800.0 * (fmod((d_nav.WN_0 - d_nav.WN_0G), 64)));
|
||||
// }
|
||||
|
||||
if (d_flag_frame_sync == true and d_nav.is_flag_TOW_set() == true)
|
||||
|
@ -410,7 +410,7 @@ int glonass_l2_ca_telemetry_decoder_gs::general_work(int noutput_items __attribu
|
||||
|
||||
// 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 + d_nav.A_1G * (d_TOW_at_current_symbol - d_nav.t_0G + 604800.0 * (fmod((d_nav.WN_0 - d_nav.WN_0G), 64)));
|
||||
// }
|
||||
|
||||
if (d_flag_frame_sync == true and d_nav.is_flag_TOW_set() == true)
|
||||
|
@ -62,13 +62,35 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga(
|
||||
std::memcpy(trk_params_fpga.signal, sig_.data(), 3);
|
||||
|
||||
// UIO device file
|
||||
device_name = configuration->property(role + ".devicename", default_device_name);
|
||||
device_name = configuration->property(role + ".devicename", default_device_name_Galileo_E1);
|
||||
|
||||
// compute the number of tracking channels that have already been instantiated. The order in which
|
||||
// GNSS-SDR instantiates the tracking channels i L1, L2, L5, E1, E5a
|
||||
num_prev_assigned_ch = configuration->property("Channels_1C.count", 0) +
|
||||
configuration->property("Channels_2S.count", 0) +
|
||||
configuration->property("Channels_L5.count", 0);
|
||||
|
||||
uint32_t num_prev_assigned_ch_1C = 0;
|
||||
std::string device_io_name;
|
||||
|
||||
if (configuration->property("Tracking_1C.devicename", default_device_name_GPS_L1) == default_device_name_GPS_L1)
|
||||
{
|
||||
for (uint32_t k = 0; k < configuration->property("Channels_1C.count", 0U); k++)
|
||||
{
|
||||
if (find_uio_dev_file_name(device_io_name, default_device_name_GPS_L1, k + 1) == 0)
|
||||
{
|
||||
num_prev_assigned_ch_1C = num_prev_assigned_ch_1C + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (configuration->property("Tracking_1C.devicename", std::string("")) != device_name)
|
||||
{
|
||||
num_prev_assigned_ch_1C = configuration->property("Channels_1C.count", 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t num_prev_assigned_ch_2S = configuration->property("Channels_2S.count", 0);
|
||||
uint32_t num_prev_assigned_ch_L5 = configuration->property("Channels_L5.count", 0);
|
||||
num_prev_assigned_ch = num_prev_assigned_ch_1C + num_prev_assigned_ch_2S + num_prev_assigned_ch_L5;
|
||||
|
||||
// ################# PRE-COMPUTE ALL THE CODES #################
|
||||
uint32_t code_samples_per_chip = 2;
|
||||
|
@ -123,7 +123,8 @@ public:
|
||||
void stop_tracking() override;
|
||||
|
||||
private:
|
||||
const std::string default_device_name = "multicorrelator_resampler_5_1_AXI"; // UIO device name
|
||||
const std::string default_device_name_Galileo_E1 = "multicorrelator_resampler_5_1_AXI"; // UIO device name
|
||||
const std::string default_device_name_GPS_L1 = "multicorrelator_resampler_S00_AXI"; // UIO device name
|
||||
|
||||
// the following flags are FPGA-specific and they are using arrange the values of the local code in the way the FPGA
|
||||
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
|
||||
|
@ -59,7 +59,7 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga(
|
||||
d_data_codes = nullptr;
|
||||
|
||||
// UIO device file
|
||||
device_name = configuration->property(role + ".devicename", default_device_name);
|
||||
device_name = configuration->property(role + ".devicename", default_device_name_Galileo_E5a);
|
||||
|
||||
// compute the number of tracking channels that have already been instantiated. The order in which
|
||||
// GNSS-SDR instantiates the tracking channels i L1, L2, L5, E1, E5a
|
||||
@ -67,9 +67,15 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga(
|
||||
// Therefore for the proper assignment of the FPGA tracking device file numbers to the E5a tracking channels,
|
||||
// the number of channels that have already been assigned to L5 must not be substracted to this channel number,
|
||||
// so they are not counted here.
|
||||
num_prev_assigned_ch = configuration->property("Channels_1C.count", 0) +
|
||||
configuration->property("Channels_2S.count", 0) +
|
||||
configuration->property("Channels_1B.count", 0);
|
||||
|
||||
uint32_t num_prev_assigned_ch_1C = configuration->property("Channels_1C.count", 0);
|
||||
uint32_t num_prev_assigned_ch_2S = 0;
|
||||
if (configuration->property("Tracking_2S.devicename", std::string("")) != device_name)
|
||||
{
|
||||
num_prev_assigned_ch_2S = configuration->property("Channels_2S.count", 0);
|
||||
}
|
||||
uint32_t num_prev_assigned_ch_1B = configuration->property("Channels_1B.count", 0);
|
||||
num_prev_assigned_ch = num_prev_assigned_ch_1C + num_prev_assigned_ch_2S + num_prev_assigned_ch_1B;
|
||||
|
||||
// ################# PRE-COMPUTE ALL THE CODES #################
|
||||
uint32_t code_samples_per_chip = 1;
|
||||
|
@ -116,7 +116,7 @@ public:
|
||||
void stop_tracking() override;
|
||||
|
||||
private:
|
||||
const std::string default_device_name = "multicorrelator_resampler_3_1_AXI"; // UIO device name
|
||||
const std::string default_device_name_Galileo_E5a = "multicorrelator_resampler_3_1_AXI"; // UIO device name
|
||||
|
||||
// the following flags are FPGA-specific and they are using arrange the values of the local code in the way the FPGA
|
||||
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
|
||||
|
@ -67,7 +67,7 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
|
||||
std::memcpy(trk_params_fpga.signal, sig_.data(), 3);
|
||||
|
||||
// UIO device file
|
||||
device_name = configuration->property(role + ".devicename", default_device_name);
|
||||
device_name = configuration->property(role + ".devicename", default_device_name_GPS_L1);
|
||||
|
||||
// compute the number of tracking channels that have already been instantiated. The order in which
|
||||
// GNSS-SDR instantiates the tracking channels i L1, l2, L5, E1, E5a
|
||||
@ -153,11 +153,31 @@ void GpsL1CaDllPllTrackingFpga::set_channel(unsigned int channel)
|
||||
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
|
||||
// find the uio device file corresponding to the tracking multicorrelator
|
||||
if (find_uio_dev_file_name(device_io_name, device_name, channel - num_prev_assigned_ch) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl;
|
||||
throw std::exception();
|
||||
bool alt_device_found = false; // alternative compatible HW accelerator device not found by default
|
||||
|
||||
// If the HW accelerator is the default one in the L1 band then look for an alternative hardware accelerator
|
||||
if (device_name == default_device_name_GPS_L1)
|
||||
{
|
||||
if (find_uio_dev_file_name(device_io_name, default_device_name_Galileo_E1, channel - num_prev_assigned_ch) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device names " << device_name << " or " << default_device_name_Galileo_E1 << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
else
|
||||
{
|
||||
alt_device_found = true; // alternative compatible HW accelerator device has been found
|
||||
}
|
||||
}
|
||||
|
||||
if (!alt_device_found)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
}
|
||||
|
||||
tracking_fpga_sc->set_channel(channel, device_io_name);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user