1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-15 20:50:33 +00:00

Merge branch 'protobuf' of https://github.com/gnss-sdr/gnss-sdr into next

This commit is contained in:
Carles Fernandez 2019-04-22 18:16:06 +02:00
commit 657ad81bbf
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
33 changed files with 1059 additions and 243 deletions

View File

@ -402,6 +402,7 @@ set(GNSSSDR_PYTHON3_MIN_VERSION "3.4")
set(GNSSSDR_MAKO_MIN_VERSION "0.4.2") set(GNSSSDR_MAKO_MIN_VERSION "0.4.2")
set(GNSSSDR_ARMADILLO_MIN_VERSION "5.300.0") set(GNSSSDR_ARMADILLO_MIN_VERSION "5.300.0")
set(GNSSSDR_MATIO_MIN_VERSION "1.5.3") set(GNSSSDR_MATIO_MIN_VERSION "1.5.3")
set(GNSSSDR_PROTOBUF_MIN_VERSION "3.0.0")
@ -416,6 +417,7 @@ set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master")
set(GNSSSDR_GPSTK_LOCAL_VERSION "2.10.6") set(GNSSSDR_GPSTK_LOCAL_VERSION "2.10.6")
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.14") set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.14")
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.9") set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.9")
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.7.1")
if(CMAKE_VERSION VERSION_LESS "3.0.2") # Fix for CentOS 7 if(CMAKE_VERSION VERSION_LESS "3.0.2") # Fix for CentOS 7
set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.1") set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.1")
@ -1784,6 +1786,131 @@ endif()
################################################################################
# Protocol Buffers https://github.com/protocolbuffers/protobuf
################################################################################
set(Protobuf_VERSION "0.0.0")
find_package(Protobuf)
set_package_properties(Protobuf PROPERTIES
URL "https://developers.google.com/protocol-buffers/"
DESCRIPTION "A language-neutral, platform-neutral extensible mechanism for serializing structured data"
PURPOSE "Used to serialize output data in a way that can be read by other applications."
TYPE REQUIRED
)
if(Protobuf_FOUND AND CMAKE_VERSION VERSION_LESS 3.9)
add_library(protobuf::libprotobuf SHARED IMPORTED)
set_target_properties(protobuf::libprotobuf PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${Protobuf_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${Protobuf_LIBRARY}"
)
add_executable(protobuf::protoc IMPORTED)
set_target_properties(protobuf::protoc PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${Protobuf_PROTOC_EXECUTABLE}"
INTERFACE_LINK_LIBRARIES "${Protobuf_PROTOC_LIBRARY}"
)
endif()
if(Protobuf_FOUND AND CMAKE_CROSSCOMPILING)
find_program(PROTOC_EXECUTABLE protoc
HINTS
/usr/local/bin/
/usr/bin/
NO_SYSTEM_ENVIRONMENT_PATH
)
if(PROTOC_EXECUTABLE)
set_target_properties(protobuf::protoc PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION ${PROTOC_EXECUTABLE}
)
else()
message(FATAL ERROR "Please install the Protocol Buffers compiter v{${Protobuf_VERSION}} in the host machine")
endif()
endif()
if((NOT Protobuf_FOUND) OR (NOT Protobuf_PROTOC_EXECUTABLE) OR (${Protobuf_VERSION} VERSION_LESS ${GNSSSDR_PROTOBUF_MIN_VERSION}))
unset(Protobuf_PROTOC_EXECUTABLE)
if(CMAKE_CROSSCOMPILING)
if(NOT Protobuf_FOUND)
ExternalProject_Add(protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
GIT_REPOSITORY https://github.com/protocolbuffers/protobuf
GIT_TAG v${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/protobuf/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/protobuf/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/autogen.sh
CONFIGURE_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/protobuf/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION} --host=$ENV{OECORE_TARGET_ARCH} --with-protoc=${PROTOC_EXECUTABLE}"
BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}protobuf${CMAKE_STATIC_LIBRARY_SUFFIX}
${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/bin/protoc
)
endif()
else()
if(CMAKE_VERSION VERSION_LESS 3.2)
ExternalProject_Add(protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
GIT_REPOSITORY https://github.com/protocolbuffers/protobuf
GIT_TAG v${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/protobuf/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/protobuf/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/autogen.sh
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/protobuf/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install
)
else()
ExternalProject_Add(protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
GIT_REPOSITORY https://github.com/protocolbuffers/protobuf
GIT_TAG v${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/protobuf/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/protobuf/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/autogen.sh
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/protobuf/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}
BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}protobuf${CMAKE_STATIC_LIBRARY_SUFFIX}
${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/bin/protoc
)
endif()
if(NOT TARGET protobuf::protoc)
add_executable(protobuf::protoc IMPORTED)
add_dependencies(protobuf::protoc protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION})
endif()
unset(Protobuf_PROTOC_EXECUTABLE)
set(PROTOBUF_PROTOC_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/bin/protoc")
set_target_properties(protobuf::protoc PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/bin/protoc"
INTERFACE_LINK_LIBRARIES "${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}protoc${CMAKE_STATIC_LIBRARY_SUFFIX}"
)
endif()
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/include)
if(NOT TARGET protobuf::libprotobuf)
add_library(protobuf::libprotobuf STATIC IMPORTED)
add_dependencies(protobuf::libprotobuf protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION})
endif()
set_target_properties(protobuf::libprotobuf PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}protobuf${CMAKE_STATIC_LIBRARY_SUFFIX}"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/include"
INTERFACE_LINK_LIBRARIES "${CMAKE_CURRENT_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}protobuf${CMAKE_STATIC_LIBRARY_SUFFIX}"
)
if(${Protobuf_VERSION} VERSION_LESS ${GNSSSDR_PROTOBUF_MIN_VERSION})
set_package_properties(Protobuf PROPERTIES
PURPOSE "Protocol Buffers found (v${Protobuf_VERSION}) is too old (> v${GNSSSDR_PROTOBUF_MIN_VERSION} needed)."
)
endif()
set_package_properties(Protobuf PROPERTIES
PURPOSE "Protocol Buffers v${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION} will be downloaded and built when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'."
)
endif()
################################################################################ ################################################################################
# Doxygen - http://www.doxygen.nl (OPTIONAL, used if found) # Doxygen - http://www.doxygen.nl (OPTIONAL, used if found)
################################################################################ ################################################################################

View File

@ -68,7 +68,7 @@ $ sudo apt-get install build-essential cmake git libboost-dev libboost-date-time
libboost-serialization-dev liblog4cpp5-dev libuhd-dev gnuradio-dev gr-osmosdr \ libboost-serialization-dev liblog4cpp5-dev libuhd-dev gnuradio-dev gr-osmosdr \
libblas-dev liblapack-dev libarmadillo-dev libgflags-dev libgoogle-glog-dev \ libblas-dev liblapack-dev libarmadillo-dev libgflags-dev libgoogle-glog-dev \
libgnutls-openssl-dev libpcap-dev python-mako python-six libmatio-dev libpugixml-dev \ libgnutls-openssl-dev libpcap-dev python-mako python-six libmatio-dev libpugixml-dev \
libgtest-dev libgtest-dev libprotobuf-dev protobuf-compiler
~~~~~~ ~~~~~~
Please note that the required files from `libgtest-dev` were moved to `googletest` in Debian 9 "stretch" and Ubuntu 18.04 "bionic", and moved back again to `libgtest-dev` in Debian 10 "buster" and Ubuntu 18.10 "cosmic". Please note that the required files from `libgtest-dev` were moved to `googletest` in Debian 9 "stretch" and Ubuntu 18.04 "bionic", and moved back again to `libgtest-dev` in Debian 10 "buster" and Ubuntu 18.10 "cosmic".
@ -86,7 +86,7 @@ If you are using Arch Linux:
~~~~~~ ~~~~~~
$ pacman -S gcc make cmake git boost boost-libs log4cpp libvolk gnuradio \ $ pacman -S gcc make cmake git boost boost-libs log4cpp libvolk gnuradio \
gnuradio-osmosdr blas lapack gflags google-glog openssl pugixml \ gnuradio-osmosdr blas lapack gflags google-glog openssl pugixml \
python-mako python-six libmatio libpcap gtest python-mako python-six libmatio libpcap gtest protobuf
~~~~~~ ~~~~~~
Once you have installed these packages, you can jump directly to [download the source code and build GNSS-SDR](#download-and-build-linux). Once you have installed these packages, you can jump directly to [download the source code and build GNSS-SDR](#download-and-build-linux).
@ -119,7 +119,8 @@ $ sudo yum install make automake gcc gcc-c++ kernel-devel cmake git boost-devel
boost-date-time boost-system boost-filesystem boost-thread boost-chrono \ boost-date-time boost-system boost-filesystem boost-thread boost-chrono \
boost-serialization log4cpp-devel gnuradio-devel gr-osmosdr-devel \ boost-serialization log4cpp-devel gnuradio-devel gr-osmosdr-devel \
blas-devel lapack-devel matio-devel armadillo-devel gflags-devel \ blas-devel lapack-devel matio-devel armadillo-devel gflags-devel \
glog-devel openssl-devel libpcap-devel python-mako python-six pugixml-devel glog-devel openssl-devel libpcap-devel python-mako python-six \
pugixml-devel protobuf-devel
~~~~~~ ~~~~~~
Once you have installed these packages, you can jump directly to [download the source code and build GNSS-SDR](#download-and-build-linux). Once you have installed these packages, you can jump directly to [download the source code and build GNSS-SDR](#download-and-build-linux).
@ -135,7 +136,7 @@ zypper install cmake git gcc-c++ boost-devel libboost_atomic-devel \
libboost_thread-devel libboost_chrono-devel libboost_serialization-devel \ libboost_thread-devel libboost_chrono-devel libboost_serialization-devel \
log4cpp-devel gtest gnuradio-devel pugixml-devel libpcap-devel \ log4cpp-devel gtest gnuradio-devel pugixml-devel libpcap-devel \
armadillo-devel libtool automake hdf5-devel libopenssl-devel python-Mako \ armadillo-devel libtool automake hdf5-devel libopenssl-devel python-Mako \
python-six python-six protobuf-devel
~~~~~~ ~~~~~~
Once you have installed these packages, you can jump directly to [download the source code and build GNSS-SDR](#download-and-build-linux). Once you have installed these packages, you can jump directly to [download the source code and build GNSS-SDR](#download-and-build-linux).
@ -283,6 +284,29 @@ In case the GnuTLS library with openssl extensions package is not available in y
#### Install [Protocol Buffers](https://developers.google.com/protocol-buffers/ "Protocol Buffers' Homepage"), a portable mechanism for serialization of structured data:
GNSS-SDR requires Protocol Buffers v3.0.0 or later. If the packages that come with your distribution are older than that (_e.g._, Ubuntu 16.04 Xenial and Debian 8 Jessie came with older versions), then you will need to install it manually. First, install the dependencies:
~~~~~~
$ sudo apt-get install autoconf automake libtool curl make g++ unzip
~~~~~~
and then:
~~~~~~
$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.7.1/protobuf-cpp-3.7.1.tar.gz
$ tar xvfz protobuf-cpp-3.7.1.tar.gz
$ cd protobuf-3.7.1
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install
$ sudo ldconfig
~~~~~~
### <a name="download-and-build-linux">Clone GNSS-SDR's Git repository</a>: ### <a name="download-and-build-linux">Clone GNSS-SDR's Git repository</a>:
~~~~~~ ~~~~~~
@ -570,6 +594,7 @@ $ sudo port install gnutls
$ sudo port install google-glog +gflags $ sudo port install google-glog +gflags
$ sudo port install matio $ sudo port install matio
$ sudo port install pugixml $ sudo port install pugixml
$ sudo port install protobuf3-cpp
$ sudo port install py27-mako $ sudo port install py27-mako
$ sudo port install py27-six $ sudo port install py27-six
$ sudo port install doxygen +docs $ sudo port install doxygen +docs
@ -617,6 +642,7 @@ $ brew install libmatio
$ brew install log4cpp $ brew install log4cpp
$ brew install openssl $ brew install openssl
$ brew install pugixml $ brew install pugixml
$ brew install protobuf
$ pip install mako $ pip install mako
$ pip install six $ pip install six
~~~~~~ ~~~~~~

View File

@ -26,6 +26,7 @@
- Fix bug in GLONASS dual frequency receiver. - Fix bug in GLONASS dual frequency receiver.
- Added a custom UDP/IP output for PVT data streaming. - Added a custom UDP/IP output for PVT data streaming.
- Improved Monitor block with UDP/IP output for internal receiver's data streaming. - Improved Monitor block with UDP/IP output for internal receiver's data streaming.
- Custom output formats described with .proto files, making easier to other applications reading them in a forward and backward-compatible fashion upon future format changes.
### Improvements in Maintainability: ### Improvements in Maintainability:
@ -51,6 +52,7 @@
- The receiver now admits FPGA off-loading, allowing for real time operation at high sampling rates and higher number of signals and channels. - The receiver now admits FPGA off-loading, allowing for real time operation at high sampling rates and higher number of signals and channels.
- Fixed program termination (avoiding hangs and segfaults in some platforms/configurations). - Fixed program termination (avoiding hangs and segfaults in some platforms/configurations).
- The Labsat_Signal_Source now terminates the receiver's execution when the end of file(s) is reached. It now accepts LabSat 2 filenames and series of LabSat 3 files.
- CMake now generates a summary of enabled/disabled features. This info is also stored in a file called features.log in the building directory. - CMake now generates a summary of enabled/disabled features. This info is also stored in a file called features.log in the building directory.
- New parameter PVT.show_local_time_zone displays time in the local time zone. Subject to the proper system configuration of the machine running the software receiver. - New parameter PVT.show_local_time_zone displays time in the local time zone. Subject to the proper system configuration of the machine running the software receiver.
- Improved information provided to the user in case of failure. - Improved information provided to the user in case of failure.

19
docs/protobuf/README.md Normal file
View File

@ -0,0 +1,19 @@
# Custom structured data format definitions
Files in this folder describe structured data formats that are generated by
GNSS-SDR. They use [Protocol Buffers](https://developers.google.com/protocol-buffers/)'
[proto3](https://developers.google.com/protocol-buffers/docs/proto3) syntax.
From those files, the protocol buffer compiler creates classes that implement
automatic encoding and parsing of the protocol buffer data with an efficient
binary format. The generated classes provide getters and setters for the fields
that make up a protocol buffer and take care of the details of reading and
writing it as a unit. Importantly, the protocol buffer format supports the idea
of extending the format over time in such a way that the code can still read
data encoded with the old format.
Just grab these files if you are developing a client application for GNSS-SDR.
You are free to use C++, Java, Python, C#, Dart, Go or Ruby, among other
languages. A tutorial to create a simple application using Protocol Buffers and
a `.proto` file in C++ is available at
https://gnss-sdr.org/docs/tutorials/monitoring-software-receiver-internal-status/

View File

@ -0,0 +1,42 @@
syntax = "proto3";
package gnss_sdr;
/* GnssSynchro represents the processing measurements at a given time taken by a given processing channel */
message GnssSynchro {
string system = 1; // GNSS constellation: "G" for GPS, "R" for Glonass, "S" for SBAS, "E" for Galileo and "C" for Beidou.
string signal = 2; // GNSS signal: "1C" for GPS L1 C/A, "1B" for Galileo E1b/c, "1G" for Glonass L1 C/A, "2S" for GPS L2 L2C(M), "2G" for Glonass L2 C/A, "L5" for GPS L5 and "5X" for Galileo E5a
uint32 prn = 3; // PRN number
int32 channel_id = 4; // Channel number
double acq_delay_samples = 5; // Coarse code delay estimation, in samples
double acq_doppler_hz = 6; // Coarse Doppler estimation in each channel, in Hz
uint64 acq_samplestamp_samples = 7; // Number of samples at signal SampleStamp
uint32 acq_doppler_step = 8; // Step of the frequency bin in the search grid, in Hz
bool flag_valid_acquisition = 9; // Acquisition status
int64 fs = 10; // Sampling frequency, in samples per second
double prompt_i = 11; // In-phase (real) component of the prompt correlator output
double prompt_q = 12; // Quadrature (imaginary) component of the prompt correlator output
double cn0_db_hz = 13; // Carrier-to-Noise density ratio, in dB-Hz
double carrier_doppler_hz = 14; // Doppler estimation, in [Hz].
double carrier_phase_rads = 15; // Carrier phase estimation, in rad
double code_phase_samples = 16; // Code phase in samples
uint64 tracking_sample_counter = 17; // Sample counter indicating the number of processed samples
bool flag_valid_symbol_output = 18; // Indicates the validity of signal tracking
int32 correlation_length_ms = 19; // Time duration of coherent correlation integration, in ms
bool flag_valid_word = 20; // Indicates the validity of the decoded navigation message word
uint32 tow_at_current_symbol_ms = 21; // Time of week of the current symbol, in ms
double pseudorange_m = 22; // Pseudorange computation, in m
double rx_time = 23; // Receiving time after the start of the week, in s
bool flag_valid_pseudorange = 24; // Pseudorange computation status
double interp_tow_ms = 25; // Interpolated time of week, in ms
}
/* Observables represents a collection of GnssSynchro annotations */
message Observables {
repeated GnssSynchro observable = 1;
}

View File

@ -0,0 +1,41 @@
syntax = "proto3";
package gnss_sdr;
/* MonitorPvt represents a search query, with pagination options to
* indicate which results to include in the response. */
message MonitorPvt {
uint32 tow_at_current_symbol_ms = 1; // Time of week of the current symbol, in ms
uint32 week = 2; // PVT GPS week
double rx_time = 3; // PVT GPS time
double user_clk_offset = 4; // User clock offset, in s
double pos_x = 5; // Position X component in ECEF, expressed in m
double pos_y = 6; // Position Y component in ECEF, expressed in m
double pos_z = 7; // Position Z component in ECEF, expressed in m
double vel_x = 8; // Velocity X component in ECEF, in m/s
double vel_y = 9; // Velocity Y component in ECEF, in m/s
double vel_z = 10; // Velocity Z component in ECEF, in m/s
double cov_xx = 11; // Position variance in the Y component, in m2
double cov_yy = 12; // Position variance in the Y component, in m2
double cov_zz = 13; // Position variance in the Z component, in m2
double cov_xy = 14; // Position XY covariance, in m2
double cov_yz = 15; // Position YZ covariance, in m2
double cov_zx = 16; // Position ZX covariance, in m2
double latitude = 17; // Latitude, in deg. Positive: North
double longitude = 18; // Longitude, in deg. Positive: East
double height = 19; // Height, in m
uint32 valid_sats = 20; // Number of valid satellites
uint32 solution_status = 21; // RTKLIB solution status
uint32 solution_type = 22; // RTKLIB solution type (0: xyz-ecef, 1: enu-baseline)
float ar_ratio_factor = 23; // Ambiguity resolution ratio factor for validation
float ar_ratio_threshold = 24; // Ambiguity resolution ratio threshold for validation
double gdop = 25; // Geometric Dilution of Precision
double pdop = 26; // Position (3D) Dilution of Precision
double hdop = 27; // Horizontal Dilution of Precision
double vdop = 28; // Vertical Dilution of Precision
}

View File

@ -741,6 +741,11 @@ Rtklib_Pvt::Rtklib_Pvt(ConfigurationInterface* configuration,
pvt_output_parameters.monitor_enabled = configuration->property(role + ".enable_monitor", false); pvt_output_parameters.monitor_enabled = configuration->property(role + ".enable_monitor", false);
pvt_output_parameters.udp_addresses = configuration->property(role + ".monitor_client_addresses", std::string("127.0.0.1")); pvt_output_parameters.udp_addresses = configuration->property(role + ".monitor_client_addresses", std::string("127.0.0.1"));
pvt_output_parameters.udp_port = configuration->property(role + ".monitor_udp_port", 1234); pvt_output_parameters.udp_port = configuration->property(role + ".monitor_udp_port", 1234);
pvt_output_parameters.protobuf_enabled = configuration->property(role + ".enable_protobuf", true);
if (configuration->property("Monitor.enable_protobuf", false) == true)
{
pvt_output_parameters.protobuf_enabled = true;
}
// Show time in local zone // Show time in local zone
pvt_output_parameters.show_local_time_zone = configuration->property(role + ".show_local_time_zone", false); pvt_output_parameters.show_local_time_zone = configuration->property(role + ".show_local_time_zone", false);

View File

@ -347,7 +347,7 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
std::sort(udp_addr_vec.begin(), udp_addr_vec.end()); 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()); udp_addr_vec.erase(std::unique(udp_addr_vec.begin(), udp_addr_vec.end()), udp_addr_vec.end());
udp_sink_ptr = std::unique_ptr<Monitor_Pvt_Udp_Sink>(new Monitor_Pvt_Udp_Sink(udp_addr_vec, conf_.udp_port)); udp_sink_ptr = std::unique_ptr<Monitor_Pvt_Udp_Sink>(new Monitor_Pvt_Udp_Sink(udp_addr_vec, conf_.udp_port, conf_.protobuf_enabled));
} }
else else
{ {

View File

@ -16,6 +16,7 @@
# along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. # along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
# #
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${CMAKE_SOURCE_DIR}/docs/protobuf/monitor_pvt.proto)
set(PVT_LIB_SOURCES set(PVT_LIB_SOURCES
pvt_solution.cc pvt_solution.cc
@ -31,6 +32,7 @@ set(PVT_LIB_SOURCES
rtklib_solver.cc rtklib_solver.cc
pvt_conf.cc pvt_conf.cc
monitor_pvt_udp_sink.cc monitor_pvt_udp_sink.cc
${PROTO_SRCS}
) )
set(PVT_LIB_HEADERS set(PVT_LIB_HEADERS
@ -48,6 +50,8 @@ set(PVT_LIB_HEADERS
pvt_conf.h pvt_conf.h
monitor_pvt_udp_sink.h monitor_pvt_udp_sink.h
monitor_pvt.h monitor_pvt.h
serdes_monitor_pvt.h
${PROTO_HDRS}
) )
list(SORT PVT_LIB_HEADERS) list(SORT PVT_LIB_HEADERS)
@ -61,6 +65,7 @@ target_link_libraries(pvt_libs
PUBLIC PUBLIC
Armadillo::armadillo Armadillo::armadillo
Boost::date_time Boost::date_time
protobuf::libprotobuf
algorithms_libs_rtklib algorithms_libs_rtklib
core_system_parameters core_system_parameters
PRIVATE PRIVATE
@ -72,9 +77,12 @@ target_link_libraries(pvt_libs
Matio::matio Matio::matio
) )
get_filename_component(PROTO_INCLUDE_HEADERS ${PROTO_HDRS} DIRECTORY)
target_include_directories(pvt_libs target_include_directories(pvt_libs
PUBLIC PUBLIC
${CMAKE_SOURCE_DIR}/src/core/receiver ${CMAKE_SOURCE_DIR}/src/core/receiver
${PROTO_INCLUDE_HEADERS}
) )
target_compile_definitions(pvt_libs PRIVATE -DGNSS_SDR_VERSION="${VERSION}") target_compile_definitions(pvt_libs PRIVATE -DGNSS_SDR_VERSION="${VERSION}")

View File

@ -35,7 +35,7 @@
#include <sstream> #include <sstream>
Monitor_Pvt_Udp_Sink::Monitor_Pvt_Udp_Sink(std::vector<std::string> addresses, const uint16_t& port) : socket{io_service} Monitor_Pvt_Udp_Sink::Monitor_Pvt_Udp_Sink(std::vector<std::string> addresses, const uint16_t& port, bool protobuf_enabled) : socket{io_service}
{ {
for (const auto& address : addresses) for (const auto& address : addresses)
{ {
@ -70,15 +70,29 @@ Monitor_Pvt_Udp_Sink::Monitor_Pvt_Udp_Sink(std::vector<std::string> addresses, c
monitor_pvt.pdop = 0.0; monitor_pvt.pdop = 0.0;
monitor_pvt.hdop = 0.0; monitor_pvt.hdop = 0.0;
monitor_pvt.vdop = 0.0; monitor_pvt.vdop = 0.0;
use_protobuf = protobuf_enabled;
if (use_protobuf)
{
serdes = Serdes_Monitor_Pvt();
}
} }
bool Monitor_Pvt_Udp_Sink::write_monitor_pvt(const Monitor_Pvt& monitor_pvt) bool Monitor_Pvt_Udp_Sink::write_monitor_pvt(const Monitor_Pvt& monitor_pvt)
{ {
std::ostringstream archive_stream; std::string outbound_data;
boost::archive::binary_oarchive oa{archive_stream}; if (use_protobuf == false)
oa << monitor_pvt; {
std::string outbound_data = archive_stream.str(); std::ostringstream archive_stream;
boost::archive::binary_oarchive oa{archive_stream};
oa << monitor_pvt;
outbound_data = archive_stream.str();
}
else
{
outbound_data = serdes.createProtobuffer(monitor_pvt);
}
for (const auto& endpoint : endpoints) for (const auto& endpoint : endpoints)
{ {

View File

@ -33,12 +33,13 @@
#define GNSS_SDR_MONITOR_PVT_UDP_SINK_H_ #define GNSS_SDR_MONITOR_PVT_UDP_SINK_H_
#include "monitor_pvt.h" #include "monitor_pvt.h"
#include "serdes_monitor_pvt.h"
#include <boost/asio.hpp> #include <boost/asio.hpp>
class Monitor_Pvt_Udp_Sink class Monitor_Pvt_Udp_Sink
{ {
public: public:
Monitor_Pvt_Udp_Sink(std::vector<std::string> addresses, const uint16_t &port); Monitor_Pvt_Udp_Sink(std::vector<std::string> addresses, const uint16_t &port, bool protobuf_enabled);
bool write_monitor_pvt(const Monitor_Pvt &monitor_pvt); bool write_monitor_pvt(const Monitor_Pvt &monitor_pvt);
private: private:
@ -47,6 +48,8 @@ private:
boost::system::error_code error; boost::system::error_code error;
std::vector<boost::asio::ip::udp::endpoint> endpoints; std::vector<boost::asio::ip::udp::endpoint> endpoints;
Monitor_Pvt monitor_pvt; Monitor_Pvt monitor_pvt;
Serdes_Monitor_Pvt serdes;
bool use_protobuf;
}; };

View File

@ -69,6 +69,7 @@ Pvt_Conf::Pvt_Conf()
rtcm_output_file_path = std::string("."); rtcm_output_file_path = std::string(".");
monitor_enabled = false; monitor_enabled = false;
protobuf_enabled = true;
udp_port = 0; udp_port = 0;
show_local_time_zone = false; show_local_time_zone = false;

View File

@ -80,6 +80,7 @@ public:
std::string rtcm_output_file_path; std::string rtcm_output_file_path;
bool monitor_enabled; bool monitor_enabled;
bool protobuf_enabled;
std::string udp_addresses; std::string udp_addresses;
int udp_port; int udp_port;

View File

@ -0,0 +1,138 @@
/*!
* \file serdes_monitor_pvt.h
* \brief Serialization / Deserialization of Monitor_Pvt objects using
* Protocol Buffers
* \author Carles Fernandez-Prades, 2019. cfernandez(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_SERDES_MONITOR_PVT_H_
#define GNSS_SDR_SERDES_MONITOR_PVT_H_
#include "monitor_pvt.h"
#include "monitor_pvt.pb.h" // file created by Protocol Buffers at compile time
/*!
* \brief This class implements serialization and deserialization of
* Monitor_Pvt objects using Protocol Buffers.
*/
class Serdes_Monitor_Pvt
{
public:
Serdes_Monitor_Pvt()
{
// 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;
monitor_.New();
}
~Serdes_Monitor_Pvt()
{
// google::protobuf::ShutdownProtobufLibrary();
}
inline std::string createProtobuffer(const Monitor_Pvt& monitor) //!< Serialization into a string
{
monitor_.Clear();
std::string data;
monitor_.set_tow_at_current_symbol_ms(monitor.TOW_at_current_symbol_ms);
monitor_.set_week(monitor.week);
monitor_.set_rx_time(monitor.RX_time);
monitor_.set_user_clk_offset(monitor.user_clk_offset);
monitor_.set_pos_x(monitor.pos_x);
monitor_.set_pos_y(monitor.pos_y);
monitor_.set_pos_z(monitor.pos_z);
monitor_.set_vel_x(monitor.vel_x);
monitor_.set_vel_y(monitor.vel_y);
monitor_.set_vel_z(monitor.vel_z);
monitor_.set_cov_xx(monitor.cov_xx);
monitor_.set_cov_yy(monitor.cov_yy);
monitor_.set_cov_zz(monitor.cov_zz);
monitor_.set_cov_xy(monitor.cov_xy);
monitor_.set_cov_yz(monitor.cov_yz);
monitor_.set_cov_yz(monitor.cov_yz);
monitor_.set_latitude(monitor.latitude);
monitor_.set_longitude(monitor.longitude);
monitor_.set_height(monitor.height);
monitor_.set_valid_sats(monitor.valid_sats);
monitor_.set_solution_status(monitor.solution_status);
monitor_.set_solution_type(monitor.solution_type);
monitor_.set_ar_ratio_factor(monitor.AR_ratio_factor);
monitor_.set_ar_ratio_threshold(monitor.AR_ratio_threshold);
monitor_.set_gdop(monitor.gdop);
monitor_.set_pdop(monitor.pdop);
monitor_.set_hdop(monitor.hdop);
monitor_.set_vdop(monitor.vdop);
monitor_.SerializeToString(&data);
return data;
}
inline Monitor_Pvt readProtobuffer(const gnss_sdr::MonitorPvt& mon) //!< Deserialization
{
Monitor_Pvt monitor;
monitor.TOW_at_current_symbol_ms = mon.tow_at_current_symbol_ms();
monitor.week = mon.week();
monitor.RX_time = mon.rx_time();
monitor.user_clk_offset = mon.user_clk_offset();
monitor.pos_x = mon.pos_x();
monitor.pos_y = mon.pos_y();
monitor.pos_z = mon.pos_z();
monitor.vel_x = mon.vel_x();
monitor.vel_y = mon.vel_y();
monitor.vel_z = mon.vel_z();
monitor.cov_xx = mon.cov_xx();
monitor.cov_yy = mon.cov_yy();
monitor.cov_zz = mon.cov_zz();
monitor.cov_xy = mon.cov_xy();
monitor.cov_yz = mon.cov_yz();
monitor.cov_zx = mon.cov_zx();
monitor.latitude = mon.latitude();
monitor.longitude = mon.longitude();
monitor.height = mon.height();
monitor.valid_sats = static_cast<uint8_t>(mon.valid_sats());
monitor.solution_status = static_cast<uint8_t>(mon.solution_status());
monitor.solution_type = static_cast<uint8_t>(mon.solution_type());
monitor.AR_ratio_factor = mon.ar_ratio_factor();
monitor.AR_ratio_threshold = mon.ar_ratio_threshold();
monitor.gdop = mon.gdop();
monitor.pdop = mon.pdop();
monitor.hdop = mon.hdop();
monitor.vdop = mon.vdop();
return monitor;
}
private:
gnss_sdr::MonitorPvt monitor_;
};
#endif // GNSS_SDR_SERDES_MONITOR_PVT_H_

View File

@ -180,14 +180,14 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters.max_num_acqs = configuration_->property(role + ".max_num_acqs", 2); acq_parameters.max_num_acqs = configuration_->property(role + ".max_num_acqs", 2);
// reference for the FPGA FFT-IFFT attenuation factor // reference for the FPGA FFT-IFFT attenuation factor
acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 12); acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 13);
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
channel_ = 0; channel_ = 0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
// temporary buffers that we can delete // temporary buffers that we can delete
delete[] code; delete[] code;
delete fft_if; delete fft_if;

View File

@ -302,6 +302,7 @@ void pcps_acquisition_fpga::set_active(bool active)
} }
num_second_acq = num_second_acq + 1; num_second_acq = num_second_acq + 1;
} }
acquisition_fpga->close_device();
if (d_test_statistics <= d_threshold) if (d_test_statistics <= d_threshold)
{ {
d_state = 0; d_state = 0;

View File

@ -177,7 +177,7 @@ void Fpga_Acquisition::run_acquisition(void)
{ {
// enable interrupts // enable interrupts
int32_t reenable = 1; int32_t reenable = 1;
int32_t disable_int = 0; //int32_t disable_int = 0;
ssize_t nbytes = TEMP_FAILURE_RETRY(write(d_fd, reinterpret_cast<void *>(&reenable), sizeof(int32_t))); ssize_t nbytes = TEMP_FAILURE_RETRY(write(d_fd, reinterpret_cast<void *>(&reenable), sizeof(int32_t)));
if (nbytes != sizeof(int32_t)) if (nbytes != sizeof(int32_t))
{ {
@ -197,11 +197,11 @@ void Fpga_Acquisition::run_acquisition(void)
std::cout << "acquisition module Interrupt number " << irq_count << std::endl; std::cout << "acquisition module Interrupt number " << irq_count << std::endl;
} }
nbytes = TEMP_FAILURE_RETRY(write(d_fd, reinterpret_cast<void *>(&disable_int), sizeof(int32_t))); // nbytes = TEMP_FAILURE_RETRY(write(d_fd, reinterpret_cast<void *>(&disable_int), sizeof(int32_t)));
if (nbytes != sizeof(int32_t)) // if (nbytes != sizeof(int32_t))
{ // {
std::cerr << "Error disabling interruptions in the FPGA." << std::endl; // std::cerr << "Error disabling interruptions in the FPGA." << std::endl;
} // }
} }

View File

@ -215,7 +215,7 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
d_flag_preamble = false; d_flag_preamble = false;
d_channel = 0; d_channel = 0;
flag_TOW_set = false; flag_TOW_set = false;
flag_PLL_180_deg_phase_locked = false;
d_symbol_history.set_capacity(d_required_symbols + 1); d_symbol_history.set_capacity(d_required_symbols + 1);
// vars for Viterbi decoder // vars for Viterbi decoder
@ -488,9 +488,6 @@ void galileo_telemetry_decoder_gs::set_channel(int32_t channel)
int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{ {
int32_t corr_value = 0;
int32_t preamble_diff = 0;
auto **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); // Get the output buffer pointer auto **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); // Get the output buffer pointer
const auto **in = reinterpret_cast<const Gnss_Synchro **>(&input_items[0]); // Get the input buffer pointer const auto **in = reinterpret_cast<const Gnss_Synchro **>(&input_items[0]); // Get the input buffer pointer
@ -513,27 +510,29 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
d_sent_tlm_failed_msg = true; d_sent_tlm_failed_msg = true;
} }
} }
if (d_symbol_history.size() > d_required_symbols)
{
// ******* preamble correlation ********
for (int32_t i = 0; i < d_samples_per_preamble; i++)
{
if (d_symbol_history[i] < 0.0) // symbols clipping
{
corr_value -= d_preamble_samples[i];
}
else
{
corr_value += d_preamble_samples[i];
}
}
}
// ******* frame sync ****************** // ******* frame sync ******************
switch (d_stat) switch (d_stat)
{ {
case 0: // no preamble information case 0: // no preamble information
{ {
//correlate with preamble
int32_t corr_value = 0;
if (d_symbol_history.size() > d_required_symbols)
{
// ******* preamble correlation ********
for (int32_t i = 0; i < d_samples_per_preamble; i++)
{
if (d_symbol_history[i] < 0.0) // symbols clipping
{
corr_value -= d_preamble_samples[i];
}
else
{
corr_value += d_preamble_samples[i];
}
}
}
if (abs(corr_value) >= d_samples_per_preamble) if (abs(corr_value) >= d_samples_per_preamble)
{ {
d_preamble_index = d_sample_counter; // record the preamble sample stamp d_preamble_index = d_sample_counter; // record the preamble sample stamp
@ -544,6 +543,24 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
} }
case 1: // possible preamble lock case 1: // possible preamble lock
{ {
//correlate with preamble
int32_t corr_value = 0;
int32_t preamble_diff = 0;
if (d_symbol_history.size() > d_required_symbols)
{
// ******* preamble correlation ********
for (int32_t i = 0; i < d_samples_per_preamble; i++)
{
if (d_symbol_history[i] < 0.0) // symbols clipping
{
corr_value -= d_preamble_samples[i];
}
else
{
corr_value += d_preamble_samples[i];
}
}
}
if (abs(corr_value) >= d_samples_per_preamble) if (abs(corr_value) >= d_samples_per_preamble)
{ {
// check preamble separation // check preamble separation
@ -554,6 +571,7 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
DLOG(INFO) << "Starting page decoder for Galileo satellite " << this->d_satellite; DLOG(INFO) << "Starting page decoder for Galileo satellite " << this->d_satellite;
d_preamble_index = d_sample_counter; // record the preamble sample stamp d_preamble_index = d_sample_counter; // record the preamble sample stamp
d_CRC_error_counter = 0; d_CRC_error_counter = 0;
if (corr_value < 0) flag_PLL_180_deg_phase_locked = true;
d_stat = 2; d_stat = 2;
} }
else else
@ -576,7 +594,7 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
case 1: // INAV case 1: // INAV
// NEW Galileo page part is received // NEW Galileo page part is received
// 0. fetch the symbols into an array // 0. fetch the symbols into an array
if (corr_value > 0) // normal PLL lock if (flag_PLL_180_deg_phase_locked == false) // normal PLL lock
{ {
for (uint32_t i = 0; i < d_frame_length_symbols; i++) for (uint32_t i = 0; i < d_frame_length_symbols; i++)
{ {
@ -595,7 +613,7 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
case 2: // FNAV case 2: // FNAV
// NEW Galileo page part is received // NEW Galileo page part is received
// 0. fetch the symbols into an array // 0. fetch the symbols into an array
if (corr_value > 0) // normal PLL lock if (flag_PLL_180_deg_phase_locked == false) // normal PLL lock
{ {
int k = 0; int k = 0;
for (uint32_t i = 0; i < d_frame_length_symbols; i++) for (uint32_t i = 0; i < d_frame_length_symbols; i++)

View File

@ -102,6 +102,7 @@ private:
bool d_sent_tlm_failed_msg; bool d_sent_tlm_failed_msg;
uint32_t d_stat; uint32_t d_stat;
bool d_flag_frame_sync; bool d_flag_frame_sync;
bool flag_PLL_180_deg_phase_locked;
bool d_flag_parity; bool d_flag_parity;
bool d_flag_preamble; bool d_flag_preamble;

View File

@ -68,55 +68,66 @@ gps_l1_ca_telemetry_decoder_gs::gps_l1_ca_telemetry_decoder_gs(
this->message_port_register_out(pmt::mp("telemetry_to_trk")); this->message_port_register_out(pmt::mp("telemetry_to_trk"));
d_last_valid_preamble = 0; d_last_valid_preamble = 0;
d_sent_tlm_failed_msg = false; d_sent_tlm_failed_msg = false;
d_max_symbols_without_valid_frame = GPS_SUBFRAME_BITS * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT * 5; //rise alarm if 5 consecutive subframes have no valid CRC
// initialize internal vars // initialize internal vars
d_dump = dump; d_dump = dump;
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
DLOG(INFO) << "Initializing GPS L1 TELEMETRY DECODER";
d_bits_per_preamble = GPS_CA_PREAMBLE_LENGTH_BITS;
d_samples_per_preamble = d_bits_per_preamble * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT;
d_preamble_period_symbols = GPS_SUBFRAME_BITS * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT;
// set the preamble // set the preamble
uint16_t preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE; d_required_symbols = GPS_SUBFRAME_BITS * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT;
// preamble bits to sampled symbols // preamble bits to sampled symbols
d_preambles_symbols = static_cast<int32_t *>(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int32_t), volk_gnsssdr_get_alignment())); d_preamble_samples = static_cast<int32_t *>(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment()));
d_frame_length_symbols = GPS_SUBFRAME_BITS * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT;
d_max_symbols_without_valid_frame = d_required_symbols * 10; //rise alarm 1 minute without valid tlm
d_page_part_symbols = static_cast<double *>(volk_gnsssdr_malloc(d_frame_length_symbols * sizeof(double), volk_gnsssdr_get_alignment()));
int32_t n = 0; int32_t n = 0;
for (uint16_t preambles_bit : preambles_bits) for (int32_t i = 0; i < d_bits_per_preamble; i++)
{ {
for (uint32_t j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++) if (GPS_CA_PREAMBLE.at(i) == '1')
{ {
if (preambles_bit == 1) for (uint32_t j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++)
{ {
d_preambles_symbols[n] = 1; d_preamble_samples[n] = 1;
n++;
} }
else }
else
{
for (uint32_t j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++)
{ {
d_preambles_symbols[n] = -1; d_preamble_samples[n] = -1;
n++;
} }
n++;
} }
} }
d_stat = 0U; d_sample_counter = 0ULL;
d_stat = 0;
d_preamble_index = 0ULL;
d_flag_frame_sync = false; d_flag_frame_sync = false;
d_prev_GPS_frame_4bytes = 0;
d_TOW_at_Preamble_ms = 0; d_flag_parity = false;
flag_TOW_set = false;
d_flag_preamble = false;
d_flag_new_tow_available = false;
d_channel = 0;
flag_PLL_180_deg_phase_locked = false;
d_preamble_time_samples = 0ULL;
d_TOW_at_current_symbol_ms = 0; d_TOW_at_current_symbol_ms = 0;
d_symbol_history.set_capacity(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); d_TOW_at_Preamble_ms = 0;
d_crc_error_synchronization_counter = 0; d_CRC_error_counter = 0;
d_current_subframe_symbol = 0; d_flag_preamble = false;
d_sample_counter = 0; d_channel = 0;
flag_TOW_set = false;
flag_PLL_180_deg_phase_locked = false;
d_prev_GPS_frame_4bytes = 0;
d_symbol_history.set_capacity(d_required_symbols);
} }
gps_l1_ca_telemetry_decoder_gs::~gps_l1_ca_telemetry_decoder_gs() gps_l1_ca_telemetry_decoder_gs::~gps_l1_ca_telemetry_decoder_gs()
{ {
volk_gnsssdr_free(d_preambles_symbols); volk_gnsssdr_free(d_preamble_samples);
d_symbol_history.clear(); volk_gnsssdr_free(d_page_part_symbols);
if (d_dump_file.is_open() == true) if (d_dump_file.is_open() == true)
{ {
try try
@ -209,11 +220,11 @@ bool gps_l1_ca_telemetry_decoder_gs::decode_subframe()
bool subframe_synchro_confirmation = false; bool subframe_synchro_confirmation = false;
bool CRC_ok = true; bool CRC_ok = true;
for (float d_subframe_symbol : d_subframe_symbols) for (float subframe_symbol : d_symbol_history)
{ {
// ******* SYMBOL TO BIT ******* // ******* SYMBOL TO BIT *******
// extended correlation to bit period is enabled in tracking! // extended correlation to bit period is enabled in tracking!
symbol_accumulator += d_subframe_symbol; // accumulate the input value in d_symbol_accumulator symbol_accumulator += subframe_symbol; // accumulate the input value in d_symbol_accumulator
symbol_accumulator_counter++; symbol_accumulator_counter++;
if (symbol_accumulator_counter == 20) if (symbol_accumulator_counter == 20)
{ {
@ -221,6 +232,11 @@ bool gps_l1_ca_telemetry_decoder_gs::decode_subframe()
if (symbol_accumulator > 0) if (symbol_accumulator > 0)
{ {
GPS_frame_4bytes += 1; // insert the telemetry bit in LSB GPS_frame_4bytes += 1; // insert the telemetry bit in LSB
//std::cout << "1";
}
else
{
//std::cout << "0";
} }
symbol_accumulator = 0; symbol_accumulator = 0;
symbol_accumulator_counter = 0; symbol_accumulator_counter = 0;
@ -276,7 +292,7 @@ bool gps_l1_ca_telemetry_decoder_gs::decode_subframe()
// NEW GPS SUBFRAME HAS ARRIVED! // NEW GPS SUBFRAME HAS ARRIVED!
if (CRC_ok) if (CRC_ok)
{ {
int32_t subframe_ID = d_nav.subframe_decoder(subframe); //d ecode the subframe int32_t subframe_ID = d_nav.subframe_decoder(subframe); //decode the subframe
if (subframe_ID > 0 and subframe_ID < 6) if (subframe_ID > 0 and subframe_ID < 6)
{ {
std::cout << "New GPS NAV message received in channel " << this->d_channel << ": " std::cout << "New GPS NAV message received in channel " << this->d_channel << ": "
@ -313,7 +329,6 @@ bool gps_l1_ca_telemetry_decoder_gs::decode_subframe()
default: default:
break; break;
} }
d_flag_new_tow_available = true;
} }
else else
{ {
@ -336,30 +351,18 @@ void gps_l1_ca_telemetry_decoder_gs::reset()
int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{ {
int32_t preamble_diff_ms = 0;
auto **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); // Get the output buffer pointer auto **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); // Get the output buffer pointer
const auto **in = reinterpret_cast<const Gnss_Synchro **>(&input_items[0]); // Get the input buffer pointer const auto **in = reinterpret_cast<const Gnss_Synchro **>(&input_items[0]); // Get the input buffer pointer
Gnss_Synchro current_symbol{}; // structure to save the synchronization information and send the output object to the next block
// 1. Copy the current tracking output // 1. Copy the current tracking output
current_symbol = in[0][0]; Gnss_Synchro current_symbol = in[0][0];
// add new symbol to the symbol queue
// record the oldest subframe symbol before inserting a new symbol into the circular buffer d_symbol_history.push_back(current_symbol.Prompt_I);
if (d_current_subframe_symbol < GPS_SUBFRAME_MS and !d_symbol_history.empty())
{
d_subframe_symbols[d_current_subframe_symbol] = d_symbol_history[0].Prompt_I;
d_current_subframe_symbol++;
}
d_symbol_history.push_back(current_symbol); // add new symbol to the symbol queue
consume_each(1);
d_flag_preamble = false;
// check if there is a problem with the telemetry of the current satellite
d_sample_counter++; // count for the processed symbols d_sample_counter++; // count for the processed symbols
if (d_sent_tlm_failed_msg == false) consume_each(1);
d_flag_preamble = false;
// check if there is a problem with the telemetry of the current satellite
if (d_stat < 2 and d_sent_tlm_failed_msg == false)
{ {
if ((d_sample_counter - d_last_valid_preamble) > d_max_symbols_without_valid_frame) if ((d_sample_counter - d_last_valid_preamble) > d_max_symbols_without_valid_frame)
{ {
@ -369,108 +372,123 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__
} }
} }
// ******* preamble correlation ********
int32_t corr_value = 0;
if ((d_symbol_history.size() == GPS_CA_PREAMBLE_LENGTH_SYMBOLS))
{
int i = 0;
for (const auto &iter : d_symbol_history)
{
if (iter.Flag_valid_symbol_output == true)
{
if (iter.Prompt_I < 0.0) // symbols clipping
{
corr_value -= d_preambles_symbols[i];
}
else
{
corr_value += d_preambles_symbols[i];
}
}
i++;
}
}
// ******* frame sync ****************** // ******* frame sync ******************
if (std::abs(corr_value) == GPS_CA_PREAMBLE_LENGTH_SYMBOLS) switch (d_stat)
{ {
//TODO: Rewrite with state machine case 0: // no preamble information
if (d_stat == 0) {
{ //correlate with preamble
// record the preamble sample stamp int32_t corr_value = 0;
d_preamble_time_samples = d_symbol_history[0].Tracking_sample_counter; // record the preamble sample stamp if (d_symbol_history.size() >= GPS_CA_PREAMBLE_LENGTH_SYMBOLS)
DLOG(INFO) << "Preamble detection for SAT " << this->d_satellite << "d_symbol_history[0].Tracking_sample_counter=" << d_symbol_history[0].Tracking_sample_counter; {
d_stat = 1; // enter into frame pre-detection status // ******* preamble correlation ********
} for (int32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++)
else if (d_stat == 1) // check 6 seconds of preamble separation {
{ if (d_symbol_history[i] < 0.0) // symbols clipping
preamble_diff_ms = std::round(((static_cast<double>(d_symbol_history[0].Tracking_sample_counter) - static_cast<double>(d_preamble_time_samples)) / static_cast<double>(d_symbol_history[0].fs)) * 1000.0); {
if (std::abs(preamble_diff_ms - GPS_SUBFRAME_MS) % GPS_SUBFRAME_MS == 0) corr_value -= d_preamble_samples[i];
{ }
DLOG(INFO) << "Preamble confirmation for SAT " << this->d_satellite; else
d_flag_preamble = true; {
d_preamble_time_samples = d_symbol_history[0].Tracking_sample_counter; // record the PRN start sample index associated to the preamble corr_value += d_preamble_samples[i];
if (!d_flag_frame_sync) }
{ }
d_flag_frame_sync = true; }
if (corr_value < 0) if (abs(corr_value) >= d_samples_per_preamble)
{ {
flag_PLL_180_deg_phase_locked = true; // PLL is locked to opposite phase! d_preamble_index = d_sample_counter; // record the preamble sample stamp
DLOG(INFO) << " PLL in opposite phase for Sat " << this->d_satellite.get_PRN(); DLOG(INFO) << "Preamble detection for GPS L1 satellite " << this->d_satellite;
} d_stat = 1; // enter into frame pre-detection status
else }
{ break;
flag_PLL_180_deg_phase_locked = false; }
} case 1: // possible preamble lock
DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " {
<< static_cast<double>(d_preamble_time_samples) / static_cast<double>(d_symbol_history[0].fs) << " [s]"; //correlate with preamble
} int32_t corr_value = 0;
int32_t preamble_diff = 0;
if (d_symbol_history.size() >= GPS_CA_PREAMBLE_LENGTH_SYMBOLS)
{
// ******* preamble correlation ********
for (int32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++)
{
if (d_symbol_history[i] < 0.0) // symbols clipping
{
corr_value -= d_preamble_samples[i];
}
else
{
corr_value += d_preamble_samples[i];
}
}
}
if (abs(corr_value) >= d_samples_per_preamble)
{
// check preamble separation
preamble_diff = static_cast<int32_t>(d_sample_counter - d_preamble_index);
if (abs(preamble_diff - d_preamble_period_symbols) == 0)
{
DLOG(INFO) << "Preamble confirmation for SAT " << this->d_satellite;
d_preamble_index = d_sample_counter; // record the preamble sample stamp
if (corr_value < 0) flag_PLL_180_deg_phase_locked = true;
d_stat = 2;
}
else
{
if (preamble_diff > d_preamble_period_symbols)
{
d_stat = 0; // start again
}
}
}
break;
}
case 2: // preamble acquired
{
if (d_sample_counter >= d_preamble_index + static_cast<uint64_t>(d_preamble_period_symbols))
{
DLOG(INFO) << "Preamble received for SAT " << this->d_satellite << "d_sample_counter=" << d_sample_counter << "\n";
// call the decoder
// 0. fetch the symbols into an array
d_preamble_index = d_sample_counter; // record the preamble sample stamp (t_P)
// try to decode the subframe: if (decode_subframe())
if (decode_subframe() == false) {
{ d_CRC_error_counter = 0;
d_crc_error_synchronization_counter++; d_flag_preamble = true; // valid preamble indicator (initialized to false every work())
if (d_crc_error_synchronization_counter > 3) d_last_valid_preamble = d_sample_counter;
{ if (!d_flag_frame_sync)
DLOG(INFO) << "TOO MANY CRC ERRORS: Lost of frame sync SAT " << this->d_satellite << std::endl; {
d_stat = 0; // lost of frame sync d_flag_frame_sync = true;
d_flag_frame_sync = false; DLOG(INFO) << " Frame sync SAT " << this->d_satellite;
flag_TOW_set = false; }
d_crc_error_synchronization_counter = 0; }
} else
} {
d_current_subframe_symbol = 0; d_CRC_error_counter++;
} d_preamble_index = d_sample_counter; // record the preamble sample stamp
} if (d_CRC_error_counter > 2)
} {
else DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite;
{ d_flag_frame_sync = false;
if (d_stat == 1) d_stat = 0;
{ d_TOW_at_current_symbol_ms = 0;
preamble_diff_ms = round(((static_cast<double>(d_symbol_history[0].Tracking_sample_counter) - static_cast<double>(d_preamble_time_samples)) / static_cast<double>(d_symbol_history[0].fs)) * 1000.0); d_TOW_at_Preamble_ms = 0;
if (preamble_diff_ms > GPS_SUBFRAME_MS) d_CRC_error_counter = 0;
{ flag_TOW_set = false;
DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff_ms; }
// std::cout << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff_ms << std::endl; }
d_stat = 0; // lost of frame sync }
d_flag_frame_sync = false; break;
flag_TOW_set = false; }
d_current_subframe_symbol = 0;
d_crc_error_synchronization_counter = 0;
d_TOW_at_current_symbol_ms = 0;
}
}
} }
// 2. Add the telemetry decoder information // 2. Add the telemetry decoder information
if (this->d_flag_preamble == true and d_flag_new_tow_available == true) if (d_flag_preamble == true)
{ {
d_TOW_at_current_symbol_ms = static_cast<uint32_t>(d_nav.d_TOW * 1000.0) + GPS_CA_PREAMBLE_DURATION_MS; d_TOW_at_current_symbol_ms = static_cast<uint32_t>(d_nav.d_TOW * 1000.0);
d_TOW_at_Preamble_ms = static_cast<uint32_t>(d_nav.d_TOW * 1000.0); d_TOW_at_Preamble_ms = static_cast<uint32_t>(d_nav.d_TOW * 1000.0);
flag_TOW_set = true; flag_TOW_set = true;
d_flag_new_tow_available = false;
d_last_valid_preamble = d_sample_counter;
} }
else else
{ {

View File

@ -73,46 +73,45 @@ private:
gps_l1_ca_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump); gps_l1_ca_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump);
gps_l1_ca_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump); gps_l1_ca_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump);
bool gps_word_parityCheck(uint32_t gpsword); bool gps_word_parityCheck(uint32_t gpsword);
bool decode_subframe(); bool decode_subframe();
bool new_decoder();
int d_crc_error_synchronization_counter; // new
int32_t d_bits_per_preamble;
int32_t d_samples_per_preamble;
int32_t d_preamble_period_symbols;
int32_t *d_preamble_samples;
uint32_t d_required_symbols;
uint32_t d_frame_length_symbols;
double *d_page_part_symbols;
bool flag_PLL_180_deg_phase_locked;
// navigation message vars
Gps_Navigation_Message d_nav;
uint32_t d_prev_GPS_frame_4bytes;
boost::circular_buffer<float> d_symbol_history;
uint64_t d_sample_counter; uint64_t d_sample_counter;
bool d_sent_tlm_failed_msg; uint64_t d_preamble_index;
uint64_t d_last_valid_preamble; uint64_t d_last_valid_preamble;
uint32_t d_max_symbols_without_valid_frame; uint32_t d_max_symbols_without_valid_frame;
int *d_preambles_symbols; bool d_sent_tlm_failed_msg;
uint32_t d_stat; uint32_t d_stat;
bool d_flag_frame_sync; bool d_flag_frame_sync;
bool d_flag_parity;
// symbols
boost::circular_buffer<Gnss_Synchro> d_symbol_history;
float d_subframe_symbols[GPS_SUBFRAME_MS]{}; // symbols per subframe
int d_current_subframe_symbol;
// bits and frame
uint32_t d_prev_GPS_frame_4bytes;
bool d_flag_preamble; bool d_flag_preamble;
bool d_flag_new_tow_available; int32_t d_CRC_error_counter;
// navigation message vars
Gps_Navigation_Message d_nav;
bool d_dump;
Gnss_Satellite d_satellite; Gnss_Satellite d_satellite;
int d_channel; int32_t d_channel;
uint64_t d_preamble_time_samples;
uint32_t d_TOW_at_Preamble_ms; uint32_t d_TOW_at_Preamble_ms;
uint32_t d_TOW_at_current_symbol_ms; uint32_t d_TOW_at_current_symbol_ms;
bool flag_TOW_set; bool flag_TOW_set;
bool flag_PLL_180_deg_phase_locked; bool d_dump;
std::string d_dump_filename; std::string d_dump_filename;
std::ofstream d_dump_file; std::ofstream d_dump_file;
}; };

View File

@ -729,7 +729,6 @@ void dll_pll_veml_tracking::start_tracking()
d_current_correlation_time_s = d_code_period; d_current_correlation_time_s = d_code_period;
// Initialize tracking ========================================== // Initialize tracking ==========================================
d_carrier_loop_filter.set_params(trk_parameters.fll_bw_hz, trk_parameters.pll_bw_hz, trk_parameters.pll_filter_order); d_carrier_loop_filter.set_params(trk_parameters.fll_bw_hz, trk_parameters.pll_bw_hz, trk_parameters.pll_filter_order);
d_code_loop_filter.set_noise_bandwidth(trk_parameters.dll_bw_hz); d_code_loop_filter.set_noise_bandwidth(trk_parameters.dll_bw_hz);
@ -1544,6 +1543,7 @@ void dll_pll_veml_tracking::stop_tracking()
d_state = 0; d_state = 0;
} }
int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{ {
@ -1575,10 +1575,6 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
double acq_trk_diff_seconds = static_cast<double>(acq_trk_diff_samples) / trk_parameters.fs_in; double acq_trk_diff_seconds = static_cast<double>(acq_trk_diff_samples) / trk_parameters.fs_in;
double delta_trk_to_acq_prn_start_samples = static_cast<double>(acq_trk_diff_samples) - d_acq_code_phase_samples; double delta_trk_to_acq_prn_start_samples = static_cast<double>(acq_trk_diff_samples) - d_acq_code_phase_samples;
// Doppler effect Fd = (C / (C + Vr)) * F
double radial_velocity = (d_signal_carrier_freq + d_acq_carrier_doppler_hz) / d_signal_carrier_freq;
// new chip and PRN sequence periods based on acq Doppler
d_code_freq_chips = radial_velocity * d_code_chip_rate;
d_code_freq_chips = d_code_chip_rate; d_code_freq_chips = d_code_chip_rate;
d_code_phase_step_chips = d_code_freq_chips / trk_parameters.fs_in; d_code_phase_step_chips = d_code_freq_chips / trk_parameters.fs_in;
d_code_phase_rate_step_chips = 0.0; d_code_phase_rate_step_chips = 0.0;

View File

@ -16,15 +16,19 @@
# along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. # along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
# #
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${CMAKE_SOURCE_DIR}/docs/protobuf/gnss_synchro.proto)
set(CORE_MONITOR_LIBS_SOURCES set(CORE_MONITOR_LIBS_SOURCES
gnss_synchro_monitor.cc gnss_synchro_monitor.cc
gnss_synchro_udp_sink.cc gnss_synchro_udp_sink.cc
${PROTO_SRCS}
) )
set(CORE_MONITOR_LIBS_HEADERS set(CORE_MONITOR_LIBS_HEADERS
gnss_synchro_monitor.h gnss_synchro_monitor.h
gnss_synchro_udp_sink.h gnss_synchro_udp_sink.h
serdes_gnss_synchro.h
${PROTO_HDRS}
) )
list(SORT CORE_MONITOR_LIBS_HEADERS) list(SORT CORE_MONITOR_LIBS_HEADERS)
@ -42,11 +46,19 @@ target_link_libraries(core_monitor
Boost::serialization Boost::serialization
Boost::system Boost::system
Gnuradio::runtime Gnuradio::runtime
protobuf::libprotobuf
core_system_parameters core_system_parameters
PRIVATE PRIVATE
Gnuradio::pmt Gnuradio::pmt
) )
get_filename_component(PROTO_INCLUDE_HEADERS ${PROTO_HDRS} DIRECTORY)
target_include_directories(core_monitor
PUBLIC
${PROTO_INCLUDE_HEADERS}
)
if(OS_IS_MACOSX) if(OS_IS_MACOSX)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # not AppleClang if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # not AppleClang
target_compile_definitions(core_monitor target_compile_definitions(core_monitor
@ -65,7 +77,10 @@ if(ENABLE_CLANG_TIDY)
endif() endif()
endif() endif()
set_property(TARGET core_monitor set_property(TARGET core_monitor
APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
$<BUILD_INTERFACE:${PROTO_INCLUDE_HEADERS}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
) )

View File

@ -41,26 +41,29 @@
gnss_synchro_monitor_sptr gnss_synchro_make_monitor(unsigned int n_channels, gnss_synchro_monitor_sptr gnss_synchro_make_monitor(unsigned int n_channels,
int decimation_factor, int decimation_factor,
int udp_port, int udp_port,
const std::vector<std::string>& udp_addresses) const std::vector<std::string>& udp_addresses,
bool enable_protobuf)
{ {
return gnss_synchro_monitor_sptr(new gnss_synchro_monitor(n_channels, return gnss_synchro_monitor_sptr(new gnss_synchro_monitor(n_channels,
decimation_factor, decimation_factor,
udp_port, udp_port,
udp_addresses)); udp_addresses,
enable_protobuf));
} }
gnss_synchro_monitor::gnss_synchro_monitor(unsigned int n_channels, gnss_synchro_monitor::gnss_synchro_monitor(unsigned int n_channels,
int decimation_factor, int decimation_factor,
int udp_port, int udp_port,
const std::vector<std::string>& udp_addresses) : gr::sync_block("gnss_synchro_monitor", const std::vector<std::string>& udp_addresses,
gr::io_signature::make(n_channels, n_channels, sizeof(Gnss_Synchro)), bool enable_protobuf) : gr::sync_block("gnss_synchro_monitor",
gr::io_signature::make(0, 0, 0)) gr::io_signature::make(n_channels, n_channels, sizeof(Gnss_Synchro)),
gr::io_signature::make(0, 0, 0))
{ {
d_decimation_factor = decimation_factor; d_decimation_factor = decimation_factor;
d_nchannels = n_channels; d_nchannels = n_channels;
udp_sink_ptr = std::unique_ptr<Gnss_Synchro_Udp_Sink>(new Gnss_Synchro_Udp_Sink(udp_addresses, udp_port)); udp_sink_ptr = std::unique_ptr<Gnss_Synchro_Udp_Sink>(new Gnss_Synchro_Udp_Sink(udp_addresses, udp_port, enable_protobuf));
count = 0; count = 0;
} }

View File

@ -50,7 +50,8 @@ using gnss_synchro_monitor_sptr = boost::shared_ptr<gnss_synchro_monitor>;
gnss_synchro_monitor_sptr gnss_synchro_make_monitor(unsigned int n_channels, gnss_synchro_monitor_sptr gnss_synchro_make_monitor(unsigned int n_channels,
int decimation_factor, int decimation_factor,
int udp_port, int udp_port,
const std::vector<std::string>& udp_addresses); const std::vector<std::string>& udp_addresses,
bool enable_protobuf);
/*! /*!
* \brief This class implements a monitoring block which allows sending * \brief This class implements a monitoring block which allows sending
@ -63,12 +64,14 @@ private:
friend gnss_synchro_monitor_sptr gnss_synchro_make_monitor(unsigned int n_channels, friend gnss_synchro_monitor_sptr gnss_synchro_make_monitor(unsigned int n_channels,
int decimation_factor, int decimation_factor,
int udp_port, int udp_port,
const std::vector<std::string>& udp_addresses); const std::vector<std::string>& udp_addresses,
bool enable_protobuf);
gnss_synchro_monitor(unsigned int n_channels, gnss_synchro_monitor(unsigned int n_channels,
int decimation_factor, int decimation_factor,
int udp_port, int udp_port,
const std::vector<std::string>& udp_addresses); const std::vector<std::string>& udp_addresses,
bool enable_protobuf);
unsigned int d_nchannels; unsigned int d_nchannels;
int d_decimation_factor; int d_decimation_factor;

View File

@ -35,8 +35,13 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
Gnss_Synchro_Udp_Sink::Gnss_Synchro_Udp_Sink(std::vector<std::string> addresses, const uint16_t& port) : socket{io_service} Gnss_Synchro_Udp_Sink::Gnss_Synchro_Udp_Sink(std::vector<std::string> addresses, const uint16_t& port, bool enable_protobuf) : socket{io_service}
{ {
use_protobuf = enable_protobuf;
if (enable_protobuf)
{
serdes = Serdes_Gnss_Synchro();
}
for (const auto& address : addresses) for (const auto& address : addresses)
{ {
boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), port); boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), port);
@ -47,11 +52,18 @@ Gnss_Synchro_Udp_Sink::Gnss_Synchro_Udp_Sink(std::vector<std::string> addresses,
bool Gnss_Synchro_Udp_Sink::write_gnss_synchro(const std::vector<Gnss_Synchro>& stocks) bool Gnss_Synchro_Udp_Sink::write_gnss_synchro(const std::vector<Gnss_Synchro>& stocks)
{ {
std::ostringstream archive_stream; std::string outbound_data;
boost::archive::binary_oarchive oa{archive_stream}; if (use_protobuf == false)
oa << stocks; {
std::string outbound_data = archive_stream.str(); std::ostringstream archive_stream;
boost::archive::binary_oarchive oa{archive_stream};
oa << stocks;
outbound_data = archive_stream.str();
}
else
{
outbound_data = serdes.createProtobuffer(stocks);
}
for (const auto& endpoint : endpoints) for (const auto& endpoint : endpoints)
{ {
socket.open(endpoint.protocol(), error); socket.open(endpoint.protocol(), error);

View File

@ -33,6 +33,7 @@
#define GNSS_SDR_GNSS_SYNCHRO_UDP_SINK_H_ #define GNSS_SDR_GNSS_SYNCHRO_UDP_SINK_H_
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "serdes_gnss_synchro.h"
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/system/error_code.hpp> #include <boost/system/error_code.hpp>
#include <cstdint> #include <cstdint>
@ -47,7 +48,7 @@
class Gnss_Synchro_Udp_Sink class Gnss_Synchro_Udp_Sink
{ {
public: public:
Gnss_Synchro_Udp_Sink(std::vector<std::string> addresses, const uint16_t& port); Gnss_Synchro_Udp_Sink(std::vector<std::string> addresses, const uint16_t& port, bool enable_protobuf);
bool write_gnss_synchro(const std::vector<Gnss_Synchro>& stocks); bool write_gnss_synchro(const std::vector<Gnss_Synchro>& stocks);
private: private:
@ -56,6 +57,8 @@ private:
boost::system::error_code error; boost::system::error_code error;
std::vector<boost::asio::ip::udp::endpoint> endpoints; std::vector<boost::asio::ip::udp::endpoint> endpoints;
std::vector<Gnss_Synchro> stocks; std::vector<Gnss_Synchro> stocks;
Serdes_Gnss_Synchro serdes;
bool use_protobuf;
}; };

View File

@ -0,0 +1,160 @@
/*!
* \file serdes_gnss_synchro.h
* \brief Serialization / Deserialization of Gnss_Synchro objects using
* Protocol Buffers
* \author Carles Fernandez-Prades, 2019. cfernandez(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_SERDES_GNSS_SYNCHRO_H_
#define GNSS_SDR_SERDES_GNSS_SYNCHRO_H_
#include "gnss_synchro.h"
#include "gnss_synchro.pb.h" // file created by Protocol Buffers at compile time
#include <cstring> // for memcpy
#include <vector>
/*!
* \brief This class implements serialization and deserialization of
* Gnss_Synchro objects using Protocol Buffers.
*/
class Serdes_Gnss_Synchro
{
public:
Serdes_Gnss_Synchro()
{
// 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;
observables.New();
}
~Serdes_Gnss_Synchro()
{
google::protobuf::ShutdownProtobufLibrary();
}
inline std::string createProtobuffer(const std::vector<Gnss_Synchro>& vgs) //!< Serialization into a string
{
observables.Clear();
std::string data;
for (auto gs : vgs)
{
gnss_sdr::GnssSynchro* obs = observables.add_observable();
char c[2];
c[0] = gs.System;
c[1] = '\0';
const std::string sys(c);
char cc[3];
cc[0] = gs.Signal[0];
cc[1] = gs.Signal[1];
cc[2] = '\0';
const std::string sig(cc);
obs->set_system(sys);
obs->set_signal(sig);
obs->set_prn(gs.PRN);
obs->set_channel_id(gs.Channel_ID);
obs->set_acq_delay_samples(gs.Acq_delay_samples);
obs->set_acq_doppler_hz(gs.Acq_doppler_hz);
obs->set_acq_samplestamp_samples(gs.Acq_samplestamp_samples);
obs->set_acq_doppler_step(gs.Acq_doppler_step);
obs->set_flag_valid_acquisition(gs.Flag_valid_acquisition);
obs->set_fs(gs.fs);
obs->set_prompt_i(gs.Prompt_I);
obs->set_prompt_q(gs.Prompt_Q);
obs->set_cn0_db_hz(gs.CN0_dB_hz);
obs->set_carrier_doppler_hz(gs.Carrier_Doppler_hz);
obs->set_code_phase_samples(gs.Code_phase_samples);
obs->set_tracking_sample_counter(gs.Tracking_sample_counter);
obs->set_flag_valid_symbol_output(gs.Flag_valid_symbol_output);
obs->set_correlation_length_ms(gs.correlation_length_ms);
obs->set_fs(gs.Flag_valid_word);
obs->set_fs(gs.TOW_at_current_symbol_ms);
obs->set_pseudorange_m(gs.Pseudorange_m);
obs->set_rx_time(gs.RX_time);
obs->set_flag_valid_pseudorange(gs.Flag_valid_pseudorange);
obs->set_interp_tow_ms(gs.interp_TOW_ms);
}
observables.SerializeToString(&data);
return data;
}
inline std::vector<Gnss_Synchro> readProtobuffer(const gnss_sdr::Observables& obs) //!< Deserialization
{
std::vector<Gnss_Synchro> vgs;
vgs.reserve(obs.observable_size());
for (int i = 0; i < obs.observable_size(); ++i)
{
const gnss_sdr::GnssSynchro& gs_read = obs.observable(i);
Gnss_Synchro gs = Gnss_Synchro();
const std::string& sys = gs_read.system();
gs.System = *sys.c_str();
const std::string& sig = gs_read.signal();
std::memcpy(static_cast<void*>(gs.Signal), sig.c_str(), 3);
gs.PRN = gs_read.prn();
gs.Channel_ID = gs_read.channel_id();
gs.Acq_delay_samples = gs_read.acq_delay_samples();
gs.Acq_doppler_hz = gs_read.acq_doppler_hz();
gs.Acq_samplestamp_samples = gs_read.acq_samplestamp_samples();
gs.Acq_doppler_step = gs_read.acq_doppler_step();
gs.Flag_valid_acquisition = gs_read.flag_valid_acquisition();
gs.fs = gs_read.fs();
gs.Prompt_I = gs_read.prompt_i();
gs.Prompt_Q = gs_read.prompt_q();
gs.CN0_dB_hz = gs_read.cn0_db_hz();
gs.Carrier_Doppler_hz = gs_read.carrier_doppler_hz();
gs.Tracking_sample_counter = gs_read.tracking_sample_counter();
gs.Flag_valid_symbol_output = gs_read.flag_valid_symbol_output();
gs.correlation_length_ms = gs_read.correlation_length_ms();
gs.Flag_valid_word = gs_read.flag_valid_word();
gs.TOW_at_current_symbol_ms = gs_read.tow_at_current_symbol_ms();
gs.Pseudorange_m = gs_read.pseudorange_m();
gs.RX_time = gs_read.rx_time();
gs.Flag_valid_pseudorange = gs_read.flag_valid_pseudorange();
gs.interp_TOW_ms = gs_read.interp_tow_ms();
vgs.push_back(gs);
}
return vgs;
}
private:
gnss_sdr::Observables observables;
};
#endif // GNSS_SDR_SERDES_GNSS_SYNCHRO_H_

View File

@ -215,7 +215,7 @@ void GNSSFlowgraph::connect()
} }
DLOG(INFO) << "blocks connected internally"; DLOG(INFO) << "blocks connected internally";
// Signal Source (i) > Signal conditioner (i) > // Signal Source (i) > Signal conditioner (i) >
#ifndef ENABLE_FPGA #ifndef ENABLE_FPGA
int RF_Channels = 0; int RF_Channels = 0;
int signal_conditioner_ID = 0; int signal_conditioner_ID = 0;
@ -444,20 +444,20 @@ void GNSSFlowgraph::connect()
// create a FIR low pass filter // create a FIR low pass filter
std::vector<float> taps; std::vector<float> taps;
// float beta = 7.0; // float beta = 7.0;
// float halfband = 0.5; // float halfband = 0.5;
// float fractional_bw = 0.4; // float fractional_bw = 0.4;
// float rate = 1.0 / static_cast<float>(decimation); // float rate = 1.0 / static_cast<float>(decimation);
// //
// float trans_width = rate * (halfband - fractional_bw); // float trans_width = rate * (halfband - fractional_bw);
// float mid_transition_band = rate * halfband - trans_width / 2.0; // float mid_transition_band = rate * halfband - trans_width / 2.0;
// //
// taps = gr::filter::firdes::low_pass(1.0, // taps = gr::filter::firdes::low_pass(1.0,
// 1.0, // 1.0,
// mid_transition_band, // mid_transition_band,
// trans_width, // trans_width,
// gr::filter::firdes::win_type::WIN_KAISER, // gr::filter::firdes::win_type::WIN_KAISER,
// beta); // beta);
taps = gr::filter::firdes::low_pass(1.0, taps = gr::filter::firdes::low_pass(1.0,
fs, fs,
@ -526,7 +526,6 @@ void GNSSFlowgraph::connect()
} }
#endif #endif
// Signal Source > Signal conditioner >> Channels >> Observables // Signal Source > Signal conditioner >> Channels >> Observables
try try
{ {
@ -556,6 +555,7 @@ void GNSSFlowgraph::connect()
} }
} }
} }
// Put channels fixed to a given satellite at the beginning of the vector, then the rest // Put channels fixed to a given satellite at the beginning of the vector, then the rest
std::vector<unsigned int> vector_of_channels; std::vector<unsigned int> vector_of_channels;
for (unsigned int i = 0; i < channels_count_; i++) for (unsigned int i = 0; i < channels_count_; i++)
@ -1169,7 +1169,6 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
} }
acq_channels_count_++; acq_channels_count_++;
DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str(); DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str();
#ifndef ENABLE_FPGA #ifndef ENABLE_FPGA
channels_[ch_index]->start_acquisition(); channels_[ch_index]->start_acquisition();
#else #else
@ -1704,7 +1703,11 @@ void GNSSFlowgraph::init()
* Instantiate the receiver monitor block, if required * Instantiate the receiver monitor block, if required
*/ */
enable_monitor_ = configuration_->property("Monitor.enable_monitor", false); enable_monitor_ = configuration_->property("Monitor.enable_monitor", false);
bool enable_protobuf = configuration_->property("Monitor.enable_protobuf", true);
if (configuration_->property("PVT.enable_protobuf", false) == true)
{
enable_protobuf = true;
}
std::string address_string = configuration_->property("Monitor.client_addresses", std::string("127.0.0.1")); std::string address_string = configuration_->property("Monitor.client_addresses", std::string("127.0.0.1"));
std::vector<std::string> udp_addr_vec = split_string(address_string, '_'); std::vector<std::string> udp_addr_vec = split_string(address_string, '_');
std::sort(udp_addr_vec.begin(), udp_addr_vec.end()); std::sort(udp_addr_vec.begin(), udp_addr_vec.end());
@ -1715,7 +1718,7 @@ void GNSSFlowgraph::init()
GnssSynchroMonitor_ = gnss_synchro_make_monitor(channels_count_, GnssSynchroMonitor_ = gnss_synchro_make_monitor(channels_count_,
configuration_->property("Monitor.decimation_factor", 1), configuration_->property("Monitor.decimation_factor", 1),
configuration_->property("Monitor.udp_port", 1234), configuration_->property("Monitor.udp_port", 1234),
udp_addr_vec); udp_addr_vec, enable_protobuf);
} }
} }

View File

@ -83,6 +83,7 @@ const int32_t GPS_L1_CA_HISTORY_DEEP = 100;
{ \ { \
1, 0, 0, 0, 1, 0, 1, 1 \ 1, 0, 0, 0, 1, 0, 1, 1 \
} }
const std::string GPS_CA_PREAMBLE = {"10001011"};
const int32_t GPS_CA_PREAMBLE_LENGTH_BITS = 8; const int32_t GPS_CA_PREAMBLE_LENGTH_BITS = 8;
const int32_t GPS_CA_PREAMBLE_LENGTH_SYMBOLS = 160; const int32_t GPS_CA_PREAMBLE_LENGTH_SYMBOLS = 160;
const double GPS_CA_PREAMBLE_DURATION_S = 0.160; const double GPS_CA_PREAMBLE_DURATION_S = 0.160;

View File

@ -66,6 +66,7 @@ DECLARE_string(log_dir);
#include "unit-tests/control-plane/gnss_block_factory_test.cc" #include "unit-tests/control-plane/gnss_block_factory_test.cc"
#include "unit-tests/control-plane/gnss_flowgraph_test.cc" #include "unit-tests/control-plane/gnss_flowgraph_test.cc"
#include "unit-tests/control-plane/in_memory_configuration_test.cc" #include "unit-tests/control-plane/in_memory_configuration_test.cc"
#include "unit-tests/control-plane/protobuf_test.cc"
#include "unit-tests/control-plane/string_converter_test.cc" #include "unit-tests/control-plane/string_converter_test.cc"
#include "unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc"
#include "unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc"
@ -119,6 +120,7 @@ DECLARE_string(log_dir);
#include "unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc" #include "unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc"
#include "unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc" #include "unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc"
#include "unit-tests/signal-processing-blocks/pvt/rtcm_test.cc" #include "unit-tests/signal-processing-blocks/pvt/rtcm_test.cc"
#include "unit-tests/signal-processing-blocks/pvt/serdes_monitor_pvt_test.cc"
#include "unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc" #include "unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc"
#include "unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc" #include "unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc"
#include "unit-tests/system-parameters/glonass_gnav_nav_message_test.cc" #include "unit-tests/system-parameters/glonass_gnav_nav_message_test.cc"

View File

@ -0,0 +1,107 @@
/*!
* \file protobuf_test.cc
* \brief This file implements tests for Serdes_Gnss_Synchro
* \author Carles Fernandez-Prades, 2019. cfernandez(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "serdes_gnss_synchro.h"
TEST(Protobuf, Works)
{
uint32_t prn_true = 17;
uint32_t prn_true2 = 23;
std::string sys = "G";
std::string sig = "1C";
Gnss_Synchro gs = Gnss_Synchro();
gs.System = *sys.c_str();
std::memcpy(static_cast<void*>(gs.Signal), sig.c_str(), 3);
gs.PRN = prn_true;
gs.Channel_ID = 3;
gs.Acq_delay_samples = 431;
gs.Acq_doppler_hz = 1234;
gs.Acq_samplestamp_samples = 10000;
gs.Acq_doppler_step = 125;
gs.Flag_valid_acquisition = true;
gs.fs = 10000000;
gs.Prompt_I = 10000.0;
gs.Prompt_Q = 0.01;
gs.CN0_dB_hz = 39;
gs.Carrier_Doppler_hz = 321;
gs.Tracking_sample_counter = 11000;
gs.Flag_valid_symbol_output = false;
gs.correlation_length_ms = 1;
gs.Flag_valid_word = false;
gs.TOW_at_current_symbol_ms = 12345;
gs.Pseudorange_m = 22000002.1;
gs.RX_time = 4321;
gs.Flag_valid_pseudorange = false;
gs.interp_TOW_ms = 20;
gs.Pseudorange_m = 22000002.1;
gs.Carrier_phase_rads = 45.4;
gs.Carrier_Doppler_hz = 321;
gs.CN0_dB_hz = 39;
Serdes_Gnss_Synchro serdes = Serdes_Gnss_Synchro();
// Create a vector of Gnss_Synchro objects
std::vector<Gnss_Synchro> vgs;
vgs.push_back(gs);
gs.PRN = prn_true2;
vgs.push_back(gs);
// Serialize data
std::string serialized_data = serdes.createProtobuffer(vgs);
// Recover data from serialization
gnss_sdr::Observables obs;
obs.ParseFromString(serialized_data);
// Check that recovered data is ok
// We can access like this:
std::vector<Gnss_Synchro> vgs_read = serdes.readProtobuffer(obs);
Gnss_Synchro gs_read = vgs_read[0];
uint32_t prn_read = gs_read.PRN;
uint32_t prn_read2 = vgs_read[1].PRN;
// or without the need of gnss_synchro:
int obs_size = obs.observable_size();
uint32_t prn_read3 = obs.observable(0).prn();
EXPECT_EQ(prn_true, prn_read);
EXPECT_EQ(prn_true2, prn_read2);
EXPECT_EQ(prn_true, prn_read3);
EXPECT_EQ(2, obs_size);
}

View File

@ -0,0 +1,47 @@
/*!
* \file serdes_monitor_pvt_test.cc
* \brief Implements Unit Test for the serdes_monitor_pvt class.
* \author Carles Fernandez_prades, 2019. cfernandez(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "serdes_monitor_pvt.h"
TEST(Serdes_Monitor_Pvt_Test, Simpletest)
{
Monitor_Pvt monitor = Monitor_Pvt();
double true_latitude = 23.4;
monitor.latitude = true_latitude;
Serdes_Monitor_Pvt serdes = Serdes_Monitor_Pvt();
std::string serialized_data = serdes.createProtobuffer(monitor);
gnss_sdr::MonitorPvt mon;
mon.ParseFromString(serialized_data);
double read_latitude = mon.latitude();
EXPECT_NEAR(true_latitude, read_latitude, 0.000001);
}