diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b4a2cb33..62f3cec71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,8 +227,14 @@ endif(NOT LINUX_DISTRIBUTION) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(OperatingSystem "Mac OS X") set(OS_IS_MACOSX TRUE) - exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION) + execute_process(COMMAND uname -v OUTPUT_VARIABLE DARWIN_VERSION) string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION}) + if(${DARWIN_VERSION} MATCHES "18") + set(MACOS_MOJAVE TRUE) + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on macOS Mojave 10.14") + endif(${DARWIN_VERSION} MATCHES "18") if(${DARWIN_VERSION} MATCHES "17") set(MACOS_HIGH_SIERRA TRUE) set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14") @@ -345,7 +351,7 @@ set(GNSSSDR_ARMADILLO_LOCAL_VERSION "9.200.x") set(GNSSSDR_GTEST_LOCAL_VERSION "1.8.1") set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master") set(GNSSSDR_GPSTK_LOCAL_VERSION "2.10.6") -set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.12") +set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.13") diff --git a/README.md b/README.md index f2fe4a607..6624d618d 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,10 @@ $ sudo apt-get install build-essential cmake git libboost-dev libboost-date-time libboost-system-dev libboost-filesystem-dev libboost-thread-dev libboost-chrono-dev \ libboost-serialization-dev liblog4cpp5-dev libuhd-dev gnuradio-dev gr-osmosdr \ libblas-dev liblapack-dev libarmadillo-dev libgflags-dev libgoogle-glog-dev \ - libgnutls-openssl-dev libpcap-dev python-mako python-six libmatio-dev googletest + libgnutls-openssl-dev libpcap-dev python-mako python-six libmatio-dev libgtest-dev ~~~~~~ -Please note that `googletest` was named `libgtest-dev` in distributions older than Debian 9 "stretch" and Ubuntu 17.04 "zesty". +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". **Note for Ubuntu 14.04 LTS "trusty" users:** you will need to build from source and install GNU Radio manually, as explained below, since GNSS-SDR requires `gnuradio-dev` >= 3.7.3, and Ubuntu 14.04 came with 3.7.2. Install all the packages above BUT EXCEPT `libuhd-dev`, `gnuradio-dev` and `gr-osmosdr` (and remove them if they are already installed in your machine), and install those dependencies using PyBOMBS. The same applies to `libmatio-dev`: Ubuntu 14.04 came with 1.5.2 and the minimum required version is 1.5.3. Please do not install the `libmatio-dev` package and install `libtool`, `automake` and `libhdf5-dev` instead. A recent version of the library will be downloaded and built automatically if CMake does not find it installed. @@ -516,10 +516,7 @@ More details can be found in our tutorial about [GNSS-SDR configuration options macOS and Mac OS X --------- - -### macOS 10.13 (High Sierra) and 10.12 (Sierra), Mac OS X 10.11 (El Capitan), 10.10 (Yosemite) and 10.9 (Mavericks). - -If you still have not installed [Xcode](https://developer.apple.com/xcode/ "Xcode"), do it now from the App Store (it's free). You will also need the Xcode Command Line Tools. Launch the Terminal, found in /Applications/Utilities/, and type: +GNSS-SDR can be built on MacOS or Mac OS X, starting from 10.9 (Mavericks) and including 10.14 (Mojave). If you still have not installed [Xcode](https://developer.apple.com/xcode/ "Xcode"), do it now from the App Store (it's free). You will also need the Xcode Command Line Tools. Launch the Terminal, found in /Applications/Utilities/, and type: ~~~~~~ $ xcode-select --install @@ -558,7 +555,7 @@ You also might need to activate a Python installation. The list of installed ver $ port select list python ~~~~~~ -and you can activate a certain version (2.7 works well) by typing: +and you can activate a certain version by typing: ~~~~~~ $ sudo port select --set python python27 diff --git a/cmake/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in index 5d4ab76f7..9b3887185 100644 --- a/cmake/cmake_uninstall.cmake.in +++ b/cmake/cmake_uninstall.cmake.in @@ -24,10 +24,10 @@ string(REGEX REPLACE "\n" ";" files "${files}") foreach(file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") - exec_program( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + execute_process( + COMMAND @CMAKE_COMMAND@ -E remove \"$ENV{DESTDIR}${file}\" OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval + RESULT_VARIABLE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") diff --git a/conf/front-end-cal.conf b/conf/front-end-cal.conf index 16bf70407..8a2b55cb5 100644 --- a/conf/front-end-cal.conf +++ b/conf/front-end-cal.conf @@ -39,7 +39,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=217 -GNSS-SDR.SUPL_MNS=7 +GNSS-SDR.SUPL_MNC=7 GNSS-SDR.SUPL_LAC=861 GNSS-SDR.SUPL_CI=40184 diff --git a/conf/gnss-sdr.conf b/conf/gnss-sdr.conf index 4c9ae11a4..353bdb2fd 100644 --- a/conf/gnss-sdr.conf +++ b/conf/gnss-sdr.conf @@ -23,7 +23,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf b/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf index ba96a533e..f437366bf 100644 --- a/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf @@ -24,7 +24,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_USRP_realtime.conf b/conf/gnss-sdr_GPS_L1_USRP_realtime.conf index b432eb6b2..323feec08 100644 --- a/conf/gnss-sdr_GPS_L1_USRP_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_USRP_realtime.conf @@ -23,7 +23,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf b/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf index 3de8486d8..b2d0604bb 100644 --- a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf @@ -21,7 +21,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_nsr.conf b/conf/gnss-sdr_GPS_L1_nsr.conf index 49ae18b56..4b0b05ae2 100644 --- a/conf/gnss-sdr_GPS_L1_nsr.conf +++ b/conf/gnss-sdr_GPS_L1_nsr.conf @@ -25,7 +25,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf b/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf index 82d382a27..dfe6e331a 100644 --- a/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf +++ b/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf @@ -25,7 +25,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf b/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf index fa8996dc7..872f56bf4 100644 --- a/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf @@ -24,7 +24,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf b/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf index e186f1da7..618341f48 100644 --- a/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf +++ b/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf b/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf index 91b952ad0..4b91a9344 100644 --- a/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf @@ -24,7 +24,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5_1C +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf b/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf index f3252578b..2cec70e8c 100644 --- a/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf @@ -24,7 +24,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf b/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf index 84753bee7..b58fc57ba 100644 --- a/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf +++ b/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf b/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf index 6d61e063b..cce644be9 100644 --- a/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf +++ b/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf @@ -23,7 +23,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf b/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf index 55a84a13e..49868f37a 100644 --- a/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf +++ b/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf @@ -23,7 +23,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_Galileo_E5a.conf b/conf/gnss-sdr_Galileo_E5a.conf index c4df4139f..81dddd613 100644 --- a/conf/gnss-sdr_Galileo_E5a.conf +++ b/conf/gnss-sdr_Galileo_E5a.conf @@ -22,7 +22,7 @@ GNSS-SDR.internal_fs_sps=32000000 ;GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com ;GNSS-SDR.SUPL_gps_acquisition_port=7275 ;GNSS-SDR.SUPL_MCC=244 -;GNSS-SDR.SUPL_MNS=5 +;GNSS-SDR.SUPL_MNC=5 ;GNSS-SDR.SUPL_LAC=0x59e2 ;GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf b/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf index f66079cb4..26d01617d 100644 --- a/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf +++ b/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf @@ -21,7 +21,7 @@ GNSS-SDR.internal_fs_sps=50000000 ;GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com ;GNSS-SDR.SUPL_gps_acquisition_port=7275 ;GNSS-SDR.SUPL_MCC=244 -;GNSS-SDR.SUPL_MNS=5 +;GNSS-SDR.SUPL_MNC=5 ;GNSS-SDR.SUPL_LAC=0x59e2 ;GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_Hybrid_ishort.conf b/conf/gnss-sdr_Hybrid_ishort.conf index 55a70b7a2..c634009f3 100644 --- a/conf/gnss-sdr_Hybrid_ishort.conf +++ b/conf/gnss-sdr_Hybrid_ishort.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf index 7b978be5b..c395a5f3c 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf @@ -21,7 +21,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf index bb5d4327e..134bfa457 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf index 2ef22b956..9552ebabe 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf index 1d7fa6097..f1e5d264b 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf index 2072f8c7d..201fff1ab 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf index 3094d8c97..48eabee34 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf index d27d98d62..7c19ebc2c 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf b/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf index 411a712ab..63746aea4 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_1C_ephemeris_port=7275 GNSS-SDR.SUPL_1C_acquisition_server=supl.google.com GNSS-SDR.SUPL_1C_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf index fb6fae1c2..9c2a86def 100644 --- a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf index 6d62e65b3..a52349af1 100644 --- a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf +++ b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf b/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf index 50e49f2e9..a3e23b001 100644 --- a/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf +++ b/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/docs/xml-schemas/README.md b/docs/xml-schemas/README.md new file mode 100644 index 000000000..e85c643fe --- /dev/null +++ b/docs/xml-schemas/README.md @@ -0,0 +1,34 @@ +# XML Schemas for Assisted GNSS-SDR + +GNSS-SDR can read assistance data from [Extensible Markup Language (XML)](https://www.w3.org/XML/) files for faster [Time-To-First-Fix](https://gnss-sdr.org/design-forces/availability/#time-to-first-fix-ttff), and can store navigation data decoded from GNSS signals in the same format. This folder provides XML Schemas which describe those XML files structure. + +[XSD (XML Schema Definition)](https://www.w3.org/XML/Schema) is a World Wide Web Consortium (W3C) recommendation that specifies how to formally describe the elements in an XML document. + + +GPS L1 C/A +---------- + + - [ephemeris_map.xsd](./ephemeris_map.xsd) - GPS NAV message ephemeris parameters. + - [iono_model.xsd](./iono_model.xsd) - GPS NAV message ionospheric model parameters. + - [utc_model.xsd](./utc_model.xsd) - GPS NAV message UTC model parameters. + - [gps_almanac_map.xsd](./gps_almanac_map.xsd) - GPS NAV message almanac. + + +GPS L2C and L5 +-------------- + + - [cnav_ephemeris_map.xsd](./cnav_ephemeris_map.xsd) - GPS CNAV message ephemeris parameters. + + +Galileo +------- + + - [gal_ephemeris_map.xsd](./gal_ephemeris_map.xsd) - Galileo ephemeris parameters. + - [gal_iono_model.xsd](./gal_iono_model.xsd) - Galileo ionospheric model parameters. + - [gal_utc_model.xsd](./gal_utc_model.xsd) - Galileo UTC model parameters. + - [gal_almanac_map.xsd](./gal_almanac_map.xsd) - Galileo almanac. + +------- + +Please check https://gnss-sdr.org/docs/sp-blocks/global-parameters/ for more information about the usage of XML files in GNSS-SDR. + diff --git a/docs/xml-schemas/cnav_ephemeris_map.xsd b/docs/xml-schemas/cnav_ephemeris_map.xsd new file mode 100644 index 000000000..139756f36 --- /dev/null +++ b/docs/xml-schemas/cnav_ephemeris_map.xsd @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/ephemeris_map.xsd b/docs/xml-schemas/ephemeris_map.xsd new file mode 100644 index 000000000..f76c5e900 --- /dev/null +++ b/docs/xml-schemas/ephemeris_map.xsd @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/gal_almanac_map.xsd b/docs/xml-schemas/gal_almanac_map.xsd new file mode 100644 index 000000000..887caf064 --- /dev/null +++ b/docs/xml-schemas/gal_almanac_map.xsd @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/gal_ephemeris_map.xsd b/docs/xml-schemas/gal_ephemeris_map.xsd new file mode 100644 index 000000000..06c541af5 --- /dev/null +++ b/docs/xml-schemas/gal_ephemeris_map.xsd @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/gal_iono_model.xsd b/docs/xml-schemas/gal_iono_model.xsd new file mode 100644 index 000000000..dc0219273 --- /dev/null +++ b/docs/xml-schemas/gal_iono_model.xsd @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/gal_utc_model.xsd b/docs/xml-schemas/gal_utc_model.xsd new file mode 100644 index 000000000..a589f94fb --- /dev/null +++ b/docs/xml-schemas/gal_utc_model.xsd @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/gps_almanac_map.xsd b/docs/xml-schemas/gps_almanac_map.xsd new file mode 100644 index 000000000..5e96b4af1 --- /dev/null +++ b/docs/xml-schemas/gps_almanac_map.xsd @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/iono_model.xsd b/docs/xml-schemas/iono_model.xsd new file mode 100644 index 000000000..26cda74bd --- /dev/null +++ b/docs/xml-schemas/iono_model.xsd @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/utc_model.xsd b/docs/xml-schemas/utc_model.xsd new file mode 100644 index 000000000..44005a628 --- /dev/null +++ b/docs/xml-schemas/utc_model.xsd @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/algorithms/PVT/adapters/rtklib_pvt.cc b/src/algorithms/PVT/adapters/rtklib_pvt.cc index 509d07886..74b2f4c5d 100644 --- a/src/algorithms/PVT/adapters/rtklib_pvt.cc +++ b/src/algorithms/PVT/adapters/rtklib_pvt.cc @@ -30,6 +30,7 @@ #include "rtklib_pvt.h" +#include "pvt_conf.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" #include @@ -54,97 +55,87 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, in_streams_(in_streams), out_streams_(out_streams) { + Pvt_Conf pvt_output_parameters = Pvt_Conf(); // dump parameters std::string default_dump_filename = "./pvt.dat"; std::string default_nmea_dump_filename = "./nmea_pvt.nmea"; std::string default_nmea_dump_devname = "/dev/tty1"; std::string default_rtcm_dump_devname = "/dev/pts/1"; DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + pvt_output_parameters.dump = configuration->property(role + ".dump", false); + pvt_output_parameters.dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + pvt_output_parameters.dump_mat = configuration->property(role + ".dump_mat", true); // output rate - int output_rate_ms = configuration->property(role + ".output_rate_ms", 500); + pvt_output_parameters.output_rate_ms = configuration->property(role + ".output_rate_ms", 500); // display rate - int display_rate_ms = configuration->property(role + ".display_rate_ms", 500); + pvt_output_parameters.display_rate_ms = configuration->property(role + ".display_rate_ms", 500); // NMEA Printer settings - bool flag_nmea_tty_port = configuration->property(role + ".flag_nmea_tty_port", false); - std::string nmea_dump_filename = configuration->property(role + ".nmea_dump_filename", default_nmea_dump_filename); + pvt_output_parameters.flag_nmea_tty_port = configuration->property(role + ".flag_nmea_tty_port", false); + pvt_output_parameters.nmea_dump_filename = configuration->property(role + ".nmea_dump_filename", default_nmea_dump_filename); std::string nmea_dump_devname = configuration->property(role + ".nmea_dump_devname", default_nmea_dump_devname); // RINEX version - int rinex_version = configuration->property(role + ".rinex_version", 3); + pvt_output_parameters.rinex_version = configuration->property(role + ".rinex_version", 3); if (FLAGS_RINEX_version.compare("3.01") == 0) { - rinex_version = 3; + pvt_output_parameters.rinex_version = 3; } else if (FLAGS_RINEX_version.compare("3.02") == 0) { - rinex_version = 3; + pvt_output_parameters.rinex_version = 3; } else if (FLAGS_RINEX_version.compare("3") == 0) { - rinex_version = 3; + pvt_output_parameters.rinex_version = 3; } else if (FLAGS_RINEX_version.compare("2.11") == 0) { - rinex_version = 2; + pvt_output_parameters.rinex_version = 2; } else if (FLAGS_RINEX_version.compare("2.10") == 0) { - rinex_version = 2; + pvt_output_parameters.rinex_version = 2; } else if (FLAGS_RINEX_version.compare("2") == 0) { - rinex_version = 2; + pvt_output_parameters.rinex_version = 2; } - int rinexobs_rate_ms = bc::lcm(configuration->property(role + ".rinexobs_rate_ms", 1000), output_rate_ms); - int rinexnav_rate_ms = bc::lcm(configuration->property(role + ".rinexnav_rate_ms", 6000), output_rate_ms); + pvt_output_parameters.rinexobs_rate_ms = bc::lcm(configuration->property(role + ".rinexobs_rate_ms", 1000), pvt_output_parameters.output_rate_ms); + pvt_output_parameters.rinexnav_rate_ms = bc::lcm(configuration->property(role + ".rinexnav_rate_ms", 6000), pvt_output_parameters.output_rate_ms); // RTCM Printer settings - bool flag_rtcm_tty_port = configuration->property(role + ".flag_rtcm_tty_port", false); - std::string rtcm_dump_devname = configuration->property(role + ".rtcm_dump_devname", default_rtcm_dump_devname); - bool flag_rtcm_server = configuration->property(role + ".flag_rtcm_server", false); - unsigned short rtcm_tcp_port = configuration->property(role + ".rtcm_tcp_port", 2101); - unsigned short rtcm_station_id = configuration->property(role + ".rtcm_station_id", 1234); + pvt_output_parameters.flag_rtcm_tty_port = configuration->property(role + ".flag_rtcm_tty_port", false); + pvt_output_parameters.rtcm_dump_devname = configuration->property(role + ".rtcm_dump_devname", default_rtcm_dump_devname); + pvt_output_parameters.flag_rtcm_server = configuration->property(role + ".flag_rtcm_server", false); + pvt_output_parameters.rtcm_tcp_port = configuration->property(role + ".rtcm_tcp_port", 2101); + pvt_output_parameters.rtcm_station_id = configuration->property(role + ".rtcm_station_id", 1234); // RTCM message rates: least common multiple with output_rate_ms - int rtcm_MT1019_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1019_rate_ms", 5000), output_rate_ms); - int rtcm_MT1020_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1020_rate_ms", 5000), output_rate_ms); - int rtcm_MT1045_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1045_rate_ms", 5000), output_rate_ms); - int rtcm_MSM_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MSM_rate_ms", 1000), output_rate_ms); - int rtcm_MT1077_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1077_rate_ms", rtcm_MSM_rate_ms), output_rate_ms); - int rtcm_MT1087_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1087_rate_ms", rtcm_MSM_rate_ms), output_rate_ms); - int rtcm_MT1097_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1097_rate_ms", rtcm_MSM_rate_ms), output_rate_ms); - std::map rtcm_msg_rate_ms; - rtcm_msg_rate_ms[1019] = rtcm_MT1019_rate_ms; - rtcm_msg_rate_ms[1020] = rtcm_MT1020_rate_ms; - rtcm_msg_rate_ms[1045] = rtcm_MT1045_rate_ms; + int rtcm_MT1019_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1019_rate_ms", 5000), pvt_output_parameters.output_rate_ms); + int rtcm_MT1020_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1020_rate_ms", 5000), pvt_output_parameters.output_rate_ms); + int rtcm_MT1045_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1045_rate_ms", 5000), pvt_output_parameters.output_rate_ms); + int rtcm_MSM_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MSM_rate_ms", 1000), pvt_output_parameters.output_rate_ms); + int rtcm_MT1077_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1077_rate_ms", rtcm_MSM_rate_ms), pvt_output_parameters.output_rate_ms); + int rtcm_MT1087_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1087_rate_ms", rtcm_MSM_rate_ms), pvt_output_parameters.output_rate_ms); + int rtcm_MT1097_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1097_rate_ms", rtcm_MSM_rate_ms), pvt_output_parameters.output_rate_ms); + //std::map rtcm_msg_rate_ms; + pvt_output_parameters.rtcm_msg_rate_ms[1019] = rtcm_MT1019_rate_ms; + pvt_output_parameters.rtcm_msg_rate_ms[1020] = rtcm_MT1020_rate_ms; + pvt_output_parameters.rtcm_msg_rate_ms[1045] = rtcm_MT1045_rate_ms; for (int k = 1071; k < 1078; k++) // All GPS MSM { - rtcm_msg_rate_ms[k] = rtcm_MT1077_rate_ms; + pvt_output_parameters.rtcm_msg_rate_ms[k] = rtcm_MT1077_rate_ms; } for (int k = 1081; k < 1088; k++) // All GLONASS MSM { - rtcm_msg_rate_ms[k] = rtcm_MT1087_rate_ms; + pvt_output_parameters.rtcm_msg_rate_ms[k] = rtcm_MT1087_rate_ms; } for (int k = 1091; k < 1098; k++) // All Galileo MSM { - rtcm_msg_rate_ms[k] = rtcm_MT1097_rate_ms; + pvt_output_parameters.rtcm_msg_rate_ms[k] = rtcm_MT1097_rate_ms; } - // getting names from the config file, if available - // default filename for assistance data - const std::string eph_default_xml_filename = "./gps_ephemeris.xml"; - const std::string utc_default_xml_filename = "./gps_utc_model.xml"; - const std::string iono_default_xml_filename = "./gps_iono.xml"; - const std::string ref_time_default_xml_filename = "./gps_ref_time.xml"; - const std::string ref_location_default_xml_filename = "./gps_ref_location.xml"; - eph_xml_filename_ = configuration->property("GNSS-SDR.SUPL_gps_ephemeris_xml", eph_default_xml_filename); - //std::string utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_utc_model.xml", utc_default_xml_filename); - //std::string iono_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_iono_xml", iono_default_xml_filename); - //std::string ref_time_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_time_xml", ref_time_default_xml_filename); - //std::string ref_location_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_location_xml", ref_location_default_xml_filename); // Infer the type of receiver /* @@ -188,47 +179,46 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, int glo_1G_count = configuration->property("Channels_1G.count", 0); int glo_2G_count = configuration->property("Channels_2G.count", 0); - unsigned int type_of_receiver = 0; + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 1; // L1 + if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 2; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 3; // L5 + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 4; // E1 + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 5; // E5a + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 6; - // *******************WARNING!!!!!!!*********** - // GPS L5 only configurable for single frequency, single system at the moment!!!!!! - if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 1; - if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 2; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 3; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 4; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 5; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 6; + if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 7; + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 8; // L1+L5 + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 9; // L1+E1 + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 10; + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 11; + if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 12; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 13; // L5+E5a + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 14; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 15; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) pvt_output_parameters.type_of_receiver = 16; + if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 17; + if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 18; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) pvt_output_parameters.type_of_receiver = 19; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) pvt_output_parameters.type_of_receiver = 20; + if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 21; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count = 0)) pvt_output_parameters.type_of_receiver = 22; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) pvt_output_parameters.type_of_receiver = 23; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) pvt_output_parameters.type_of_receiver = 24; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count != 0)) pvt_output_parameters.type_of_receiver = 25; + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 26; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 27; + if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 28; + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) pvt_output_parameters.type_of_receiver = 29; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) pvt_output_parameters.type_of_receiver = 30; + if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) pvt_output_parameters.type_of_receiver = 31; - if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 7; - //if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 8; - if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 9; - if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 10; - if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 11; - if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 12; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 13; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 14; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 15; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 16; - if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 17; - if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 18; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 19; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 20; - if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 21; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count = 0)) type_of_receiver = 22; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 23; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 24; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count != 0)) type_of_receiver = 25; - if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 26; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 27; - if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 28; - if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 29; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 30; - if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 31; - //RTKLIB PVT solver options + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 32; // L1+E1+L5+E5a + + // RTKLIB PVT solver options // Settings 1 int positioning_mode = -1; std::string default_pos_mode("Single"); - std::string positioning_mode_str = configuration->property(role + ".positioning_mode", default_pos_mode); /* (PMODE_XXX) see src/algorithms/libs/rtklib/rtklib.h */ + std::string positioning_mode_str = configuration->property(role + ".positioning_mode", default_pos_mode); // (PMODE_XXX) see src/algorithms/libs/rtklib/rtklib.h if (positioning_mode_str.compare("Single") == 0) positioning_mode = PMODE_SINGLE; if (positioning_mode_str.compare("Static") == 0) positioning_mode = PMODE_STATIC; if (positioning_mode_str.compare("Kinematic") == 0) positioning_mode = PMODE_KINEMA; @@ -489,8 +479,29 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, rtkinit(&rtk, &rtklib_configuration_options); + // Outputs + bool default_output_enabled = configuration->property(role + ".output_enabled", true); + pvt_output_parameters.output_enabled = default_output_enabled; + pvt_output_parameters.rinex_output_enabled = configuration->property(role + ".rinex_output_enabled", default_output_enabled); + pvt_output_parameters.gpx_output_enabled = configuration->property(role + ".gpx_output_enabled", default_output_enabled); + pvt_output_parameters.geojson_output_enabled = configuration->property(role + ".geojson_output_enabled", default_output_enabled); + pvt_output_parameters.kml_output_enabled = configuration->property(role + ".kml_output_enabled", default_output_enabled); + pvt_output_parameters.xml_output_enabled = configuration->property(role + ".xml_output_enabled", default_output_enabled); + pvt_output_parameters.nmea_output_file_enabled = configuration->property(role + ".nmea_output_file_enabled", default_output_enabled); + pvt_output_parameters.rtcm_output_file_enabled = configuration->property(role + ".rtcm_output_file_enabled", default_output_enabled); + + std::string default_output_path = configuration->property(role + ".output_path", std::string(".")); + pvt_output_parameters.output_path = default_output_path; + pvt_output_parameters.rinex_output_path = configuration->property(role + ".rinex_output_path", default_output_path); + pvt_output_parameters.gpx_output_path = configuration->property(role + ".gpx_output_path", default_output_path); + pvt_output_parameters.geojson_output_path = configuration->property(role + ".geojson_output_path", default_output_path); + pvt_output_parameters.kml_output_path = configuration->property(role + ".kml_output_path", default_output_path); + pvt_output_parameters.xml_output_path = configuration->property(role + ".xml_output_path", default_output_path); + pvt_output_parameters.nmea_output_file_path = configuration->property(role + ".nmea_output_file_path", default_output_path); + pvt_output_parameters.rtcm_output_file_path = configuration->property(role + ".rtcm_output_file_path", default_output_path); + // make PVT object - pvt_ = rtklib_make_pvt_cc(in_streams_, dump_, dump_filename_, output_rate_ms, display_rate_ms, flag_nmea_tty_port, nmea_dump_filename, nmea_dump_devname, rinex_version, rinexobs_rate_ms, rinexnav_rate_ms, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_msg_rate_ms, rtcm_dump_devname, type_of_receiver, rtk); + pvt_ = rtklib_make_pvt_cc(in_streams_, pvt_output_parameters, rtk); DLOG(INFO) << "pvt(" << pvt_->unique_id() << ")"; if (out_streams_ > 0) { @@ -499,40 +510,9 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, } -bool RtklibPvt::save_assistance_to_XML() -{ - LOG(INFO) << "SUPL: Try to save GPS ephemeris to XML file " << eph_xml_filename_; - std::map eph_map = pvt_->get_GPS_L1_ephemeris_map(); - - if (eph_map.empty() == false) - { - std::ofstream ofs; - try - { - ofs.open(eph_xml_filename_.c_str(), std::ofstream::trunc | std::ofstream::out); - boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", eph_map); - LOG(INFO) << "Saved GPS L1 Ephemeris map data"; - } - catch (const std::exception& e) - { - LOG(WARNING) << e.what(); - return false; - } - } - else - { - LOG(WARNING) << "Failed to save Ephemeris, map is empty"; - return false; - } - return true; // return variable (true == succeeded) -} - - RtklibPvt::~RtklibPvt() { rtkfree(&rtk); - save_assistance_to_XML(); } diff --git a/src/algorithms/PVT/adapters/rtklib_pvt.h b/src/algorithms/PVT/adapters/rtklib_pvt.h index 936fd1632..c79519581 100644 --- a/src/algorithms/PVT/adapters/rtklib_pvt.h +++ b/src/algorithms/PVT/adapters/rtklib_pvt.h @@ -40,7 +40,7 @@ class ConfigurationInterface; /*! - * \brief This class implements a PvtInterface for Galileo E1 + * \brief This class implements a PvtInterface for the RTKLIB PVT block */ class RtklibPvt : public PvtInterface { @@ -87,8 +87,6 @@ private: std::string role_; unsigned int in_streams_; unsigned int out_streams_; - std::string eph_xml_filename_; - bool save_assistance_to_XML(); }; #endif diff --git a/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt b/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt index 72ce3f436..adaac0125 100644 --- a/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt @@ -36,6 +36,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/core/receiver ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib + ${CMAKE_SOURCE_DIR}/src/algorithms/libs ${ARMADILLO_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${GLOG_INCLUDE_DIRS} diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc index 2f9bb177d..fe2cce6e1 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc @@ -29,11 +29,16 @@ */ #include "rtklib_pvt_cc.h" +#include "galileo_almanac.h" +#include "galileo_almanac_helper.h" +#include "pvt_conf.h" #include "display.h" +#include "gnss_sdr_create_directory.h" #include #include #include #include +#include #include #include #include @@ -50,52 +55,15 @@ namespace bc = boost::math; namespace bc = boost::integer; #endif -//includes used by the observables serializarion (export observables for rtklib unit test) -#include -#include -#include - using google::LogMessage; rtklib_pvt_cc_sptr rtklib_make_pvt_cc(uint32_t nchannels, - bool dump, - std::string dump_filename, - int32_t output_rate_ms, - int32_t display_rate_ms, - bool flag_nmea_tty_port, - std::string nmea_dump_filename, - std::string nmea_dump_devname, - int32_t rinex_version, - int32_t rinexobs_rate_ms, - int32_t rinexnav_rate_ms, - bool flag_rtcm_server, - bool flag_rtcm_tty_port, - uint16_t rtcm_tcp_port, - uint16_t rtcm_station_id, - std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname, - const uint32_t type_of_receiver, + const Pvt_Conf& conf_, rtk_t& rtk) { return rtklib_pvt_cc_sptr(new rtklib_pvt_cc(nchannels, - dump, - dump_filename, - output_rate_ms, - display_rate_ms, - flag_nmea_tty_port, - nmea_dump_filename, - nmea_dump_devname, - rinex_version, - rinexobs_rate_ms, - rinexnav_rate_ms, - flag_rtcm_server, - flag_rtcm_tty_port, - rtcm_tcp_port, - rtcm_station_id, - rtcm_msg_rate_ms, - rtcm_dump_devname, - type_of_receiver, + conf_, rtk)); } @@ -160,6 +128,15 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) DLOG(INFO) << "New CNAV UTC record has arrived "; } + else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) + { + // ### GPS ALMANAC ### + std::shared_ptr gps_almanac; + gps_almanac = boost::any_cast>(pmt::any_ref(msg)); + d_ls_pvt->gps_almanac_map[gps_almanac->i_satellite_PRN] = *gps_almanac; + DLOG(INFO) << "New GPS almanac record has arrived "; + } + // **************** Galileo telemetry ******************** else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) { @@ -189,14 +166,28 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) d_ls_pvt->galileo_utc_model = *galileo_utc_model; DLOG(INFO) << "New UTC record has arrived "; } + else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) + { + // ### Galileo Almanac ### + std::shared_ptr galileo_almanac_helper; + galileo_almanac_helper = boost::any_cast>(pmt::any_ref(msg)); + + Galileo_Almanac sv1 = galileo_almanac_helper->get_almanac(1); + Galileo_Almanac sv2 = galileo_almanac_helper->get_almanac(2); + Galileo_Almanac sv3 = galileo_almanac_helper->get_almanac(3); + + if (sv1.i_satellite_PRN != 0) d_ls_pvt->galileo_almanac_map[sv1.i_satellite_PRN] = sv1; + if (sv2.i_satellite_PRN != 0) d_ls_pvt->galileo_almanac_map[sv2.i_satellite_PRN] = sv2; + if (sv3.i_satellite_PRN != 0) d_ls_pvt->galileo_almanac_map[sv3.i_satellite_PRN] = sv3; + DLOG(INFO) << "New Galileo Almanac data have arrived "; + } else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) { // ### Galileo Almanac ### - std::shared_ptr galileo_almanac; - galileo_almanac = boost::any_cast>(pmt::any_ref(msg)); - // update/insert new ephemeris record to the global ephemeris map - d_ls_pvt->galileo_almanac = *galileo_almanac; - DLOG(INFO) << "New Galileo Almanac has arrived "; + std::shared_ptr galileo_alm; + galileo_alm = boost::any_cast>(pmt::any_ref(msg)); + // update/insert new almanac record to the global almanac map + d_ls_pvt->galileo_almanac_map[galileo_alm->i_satellite_PRN] = *galileo_alm; } // **************** GLONASS GNAV Telemetry ************************** @@ -250,34 +241,53 @@ std::map rtklib_pvt_cc::get_GPS_L1_ephemeris_map() rtklib_pvt_cc::rtklib_pvt_cc(uint32_t nchannels, - bool dump, - std::string dump_filename, - int32_t output_rate_ms, - int32_t display_rate_ms, - bool flag_nmea_tty_port, - std::string nmea_dump_filename, - std::string nmea_dump_devname, - int32_t rinex_version, - int32_t rinexobs_rate_ms, - int32_t rinexnav_rate_ms, - bool flag_rtcm_server, - bool flag_rtcm_tty_port, - uint16_t rtcm_tcp_port, - uint16_t rtcm_station_id, - std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname, - const uint32_t type_of_receiver, + const Pvt_Conf& conf_, rtk_t& rtk) : gr::sync_block("rtklib_pvt_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)), gr::io_signature::make(0, 0, 0)) { - d_output_rate_ms = output_rate_ms; - d_display_rate_ms = display_rate_ms; - d_dump = dump; + d_output_rate_ms = conf_.output_rate_ms; + d_display_rate_ms = conf_.display_rate_ms; + d_dump = conf_.dump; + d_dump_mat = conf_.dump_mat and d_dump; + d_dump_filename = conf_.dump_filename; + std::string dump_ls_pvt_filename = conf_.dump_filename; + if (d_dump) + { + std::string dump_path; + // Get path + if (d_dump_filename.find_last_of("/") != std::string::npos) + { + 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 = "pvt"; + } + // 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(".")); + } + dump_ls_pvt_filename = dump_path + boost::filesystem::path::preferred_separator + d_dump_filename; + dump_ls_pvt_filename.append(".dat"); + // create directory + if (!gnss_sdr_create_directory(dump_path)) + { + std::cerr << "GNSS-SDR cannot create dump file for the PVT block. Wrong permissions?" << std::endl; + d_dump = false; + } + } + d_nchannels = nchannels; - d_dump_filename = dump_filename; - std::string dump_ls_pvt_filename = dump_filename; - type_of_rx = type_of_receiver; + + type_of_rx = conf_.type_of_receiver; // GPS Ephemeris data message port in this->message_port_register_in(pmt::mp("telemetry")); @@ -286,98 +296,183 @@ rtklib_pvt_cc::rtklib_pvt_cc(uint32_t nchannels, // initialize kml_printer std::string kml_dump_filename; kml_dump_filename = d_dump_filename; - d_kml_dump = std::make_shared(); - d_kml_dump->set_headers(kml_dump_filename); + d_kml_output_enabled = conf_.kml_output_enabled; + if (d_kml_output_enabled) + { + d_kml_dump = std::make_shared(conf_.kml_output_path); + d_kml_dump->set_headers(kml_dump_filename); + } + else + { + d_kml_dump = nullptr; + } // initialize gpx_printer std::string gpx_dump_filename; gpx_dump_filename = d_dump_filename; - d_gpx_dump = std::make_shared(); - d_gpx_dump->set_headers(gpx_dump_filename); + d_gpx_output_enabled = conf_.gpx_output_enabled; + if (d_gpx_output_enabled) + { + d_gpx_dump = std::make_shared(conf_.gpx_output_path); + d_gpx_dump->set_headers(gpx_dump_filename); + } + else + { + d_gpx_dump = nullptr; + } // initialize geojson_printer std::string geojson_dump_filename; geojson_dump_filename = d_dump_filename; - d_geojson_printer = std::make_shared(); - d_geojson_printer->set_headers(geojson_dump_filename); + + d_geojson_output_enabled = conf_.geojson_output_enabled; + if (d_geojson_output_enabled) + { + d_geojson_printer = std::make_shared(conf_.geojson_output_path); + d_geojson_printer->set_headers(geojson_dump_filename); + } + else + { + d_geojson_printer = nullptr; + } // initialize nmea_printer - d_nmea_printer = std::make_shared(nmea_dump_filename, flag_nmea_tty_port, nmea_dump_devname); + d_nmea_printer = std::make_shared(conf_.nmea_dump_filename, conf_.nmea_output_file_enabled, conf_.flag_nmea_tty_port, conf_.nmea_dump_devname, conf_.nmea_output_file_path); // initialize rtcm_printer std::string rtcm_dump_filename; rtcm_dump_filename = d_dump_filename; - d_rtcm_printer = std::make_shared(rtcm_dump_filename, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname); - if (rtcm_msg_rate_ms.find(1019) != rtcm_msg_rate_ms.end()) + if (conf_.flag_rtcm_server or conf_.flag_rtcm_tty_port or conf_.rtcm_output_file_enabled) { - d_rtcm_MT1019_rate_ms = rtcm_msg_rate_ms[1019]; + d_rtcm_printer = std::make_shared(rtcm_dump_filename, conf_.rtcm_output_file_enabled, conf_.flag_rtcm_server, conf_.flag_rtcm_tty_port, conf_.rtcm_tcp_port, conf_.rtcm_station_id, conf_.rtcm_dump_devname, true, conf_.rtcm_output_file_path); + std::map rtcm_msg_rate_ms = conf_.rtcm_msg_rate_ms; + if (rtcm_msg_rate_ms.find(1019) != rtcm_msg_rate_ms.end()) + { + d_rtcm_MT1019_rate_ms = rtcm_msg_rate_ms[1019]; + } + else + { + d_rtcm_MT1019_rate_ms = bc::lcm(5000, d_output_rate_ms); // default value if not set + } + if (rtcm_msg_rate_ms.find(1020) != rtcm_msg_rate_ms.end()) + { + d_rtcm_MT1020_rate_ms = rtcm_msg_rate_ms[1020]; + } + else + { + d_rtcm_MT1020_rate_ms = bc::lcm(5000, d_output_rate_ms); // default value if not set + } + if (rtcm_msg_rate_ms.find(1045) != rtcm_msg_rate_ms.end()) + { + d_rtcm_MT1045_rate_ms = rtcm_msg_rate_ms[1045]; + } + else + { + d_rtcm_MT1045_rate_ms = bc::lcm(5000, d_output_rate_ms); // default value if not set + } + if (rtcm_msg_rate_ms.find(1077) != rtcm_msg_rate_ms.end()) // whatever between 1071 and 1077 + { + d_rtcm_MT1077_rate_ms = rtcm_msg_rate_ms[1077]; + } + else + { + d_rtcm_MT1077_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set + } + if (rtcm_msg_rate_ms.find(1087) != rtcm_msg_rate_ms.end()) // whatever between 1081 and 1087 + { + d_rtcm_MT1087_rate_ms = rtcm_msg_rate_ms[1087]; + } + else + { + d_rtcm_MT1087_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set + } + if (rtcm_msg_rate_ms.find(1097) != rtcm_msg_rate_ms.end()) // whatever between 1091 and 1097 + { + d_rtcm_MT1097_rate_ms = rtcm_msg_rate_ms[1097]; + d_rtcm_MSM_rate_ms = rtcm_msg_rate_ms[1097]; + } + else + { + d_rtcm_MT1097_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set + d_rtcm_MSM_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set + } + b_rtcm_writing_started = false; + b_rtcm_enabled = true; } else { - d_rtcm_MT1019_rate_ms = bc::lcm(5000, d_output_rate_ms); // default value if not set + d_rtcm_MT1019_rate_ms = 0; + d_rtcm_MT1045_rate_ms = 0; + d_rtcm_MT1020_rate_ms = 0; + d_rtcm_MT1077_rate_ms = 0; + d_rtcm_MT1087_rate_ms = 0; + d_rtcm_MT1097_rate_ms = 0; + d_rtcm_MSM_rate_ms = 0; + b_rtcm_enabled = false; + b_rtcm_writing_started = false; + d_rtcm_printer = nullptr; } - if (rtcm_msg_rate_ms.find(1020) != rtcm_msg_rate_ms.end()) - { - d_rtcm_MT1020_rate_ms = rtcm_msg_rate_ms[1020]; - } - else - { - d_rtcm_MT1020_rate_ms = bc::lcm(5000, d_output_rate_ms); // default value if not set - } - if (rtcm_msg_rate_ms.find(1045) != rtcm_msg_rate_ms.end()) - { - d_rtcm_MT1045_rate_ms = rtcm_msg_rate_ms[1045]; - } - else - { - d_rtcm_MT1045_rate_ms = bc::lcm(5000, d_output_rate_ms); // default value if not set - } - if (rtcm_msg_rate_ms.find(1077) != rtcm_msg_rate_ms.end()) // whatever between 1071 and 1077 - { - d_rtcm_MT1077_rate_ms = rtcm_msg_rate_ms[1077]; - } - else - { - d_rtcm_MT1077_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set - } - if (rtcm_msg_rate_ms.find(1087) != rtcm_msg_rate_ms.end()) // whatever between 1081 and 1087 - { - d_rtcm_MT1087_rate_ms = rtcm_msg_rate_ms[1087]; - } - else - { - d_rtcm_MT1087_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set - } - if (rtcm_msg_rate_ms.find(1097) != rtcm_msg_rate_ms.end()) // whatever between 1091 and 1097 - { - d_rtcm_MT1097_rate_ms = rtcm_msg_rate_ms[1097]; - d_rtcm_MSM_rate_ms = rtcm_msg_rate_ms[1097]; - } - else - { - d_rtcm_MT1097_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set - d_rtcm_MSM_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set - } - b_rtcm_writing_started = false; // initialize RINEX printer b_rinex_header_written = false; b_rinex_header_updated = false; - d_rinex_version = rinex_version; - rp = std::make_shared(d_rinex_version); - d_rinexobs_rate_ms = rinexobs_rate_ms; - d_rinexnav_rate_ms = rinexnav_rate_ms; + b_rinex_output_enabled = conf_.rinex_output_enabled; + d_rinex_version = conf_.rinex_version; + if (b_rinex_output_enabled) + { + rp = std::make_shared(d_rinex_version, conf_.rinex_output_path); + } + else + { + rp = nullptr; + } + d_rinexobs_rate_ms = conf_.rinexobs_rate_ms; + d_rinexnav_rate_ms = conf_.rinexnav_rate_ms; - dump_ls_pvt_filename.append("_pvt.dat"); + // XML printer + d_xml_storage = conf_.xml_output_enabled; + if (d_xml_storage) + { + xml_base_path = conf_.xml_output_path; + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(xml_base_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(xml_base_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + xml_base_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + xml_base_path = p.string(); + } + if (xml_base_path.compare(".") != 0) + { + std::cout << "XML files will be stored at " << xml_base_path << std::endl; + } - d_ls_pvt = std::make_shared(static_cast(nchannels), dump_ls_pvt_filename, d_dump, rtk); + xml_base_path = xml_base_path + boost::filesystem::path::preferred_separator; + } + + d_ls_pvt = std::make_shared(static_cast(nchannels), dump_ls_pvt_filename, d_dump, d_dump_mat, rtk); d_ls_pvt->set_averaging_depth(1); d_rx_time = 0.0; d_last_status_print_seg = 0; - // Create Sys V message queue first_fix = true; sysv_msg_key = 1101; @@ -394,97 +489,315 @@ rtklib_pvt_cc::rtklib_pvt_cc(uint32_t nchannels, rtklib_pvt_cc::~rtklib_pvt_cc() { msgctl(sysv_msqid, IPC_RMID, NULL); - - // save GPS L2CM ephemeris to XML file - std::string file_name = "eph_GPS_CNAV.xml"; - - if (d_ls_pvt->gps_cnav_ephemeris_map.empty() == false) + if (d_xml_storage) { - std::ofstream ofs; - try + // save GPS L2CM ephemeris to XML file + std::string file_name = xml_base_path + "gps_cnav_ephemeris.xml"; + if (d_ls_pvt->gps_cnav_ephemeris_map.empty() == false) { - ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); - boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->gps_cnav_ephemeris_map); - LOG(INFO) << "Saved GPS L2CM or L5 Ephemeris map data"; + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_cnav_ephemeris_map", d_ls_pvt->gps_cnav_ephemeris_map); + LOG(INFO) << "Saved GPS L2CM or L5 Ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } } - catch (std::exception& e) + else { - LOG(WARNING) << e.what(); + LOG(INFO) << "Failed to save GPS L2CM or L5 Ephemeris, map is empty"; } - } - else - { - LOG(WARNING) << "Failed to save GPS L2CM or L5 Ephemeris, map is empty"; - } - // save GPS L1 CA ephemeris to XML file - file_name = "eph_GPS_L1CA.xml"; + // save GPS L1 CA ephemeris to XML file + file_name = xml_base_path + "gps_ephemeris.xml"; + if (d_ls_pvt->gps_ephemeris_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->gps_ephemeris_map); + LOG(INFO) << "Saved GPS L1 CA Ephemeris map data"; + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GPS L1 CA Ephemeris, map is empty"; + } - if (d_ls_pvt->gps_ephemeris_map.empty() == false) - { - std::ofstream ofs; - try + // save Galileo E1 ephemeris to XML file + file_name = xml_base_path + "gal_ephemeris.xml"; + if (d_ls_pvt->galileo_ephemeris_map.empty() == false) { - ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); - boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->gps_ephemeris_map); - LOG(INFO) << "Saved GPS L1 CA Ephemeris map data"; + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_ephemeris_map", d_ls_pvt->galileo_ephemeris_map); + LOG(INFO) << "Saved Galileo E1 Ephemeris map data"; + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } } - catch (const std::exception& e) + else { - LOG(WARNING) << e.what(); + LOG(INFO) << "Failed to save Galileo E1 Ephemeris, map is empty"; } - } - else - { - LOG(WARNING) << "Failed to save GPS L1 CA Ephemeris, map is empty"; - } - // save Galileo E1 ephemeris to XML file - file_name = "eph_Galileo_E1.xml"; + // save GLONASS GNAV ephemeris to XML file + file_name = xml_base_path + "eph_GLONASS_GNAV.xml"; + if (d_ls_pvt->glonass_gnav_ephemeris_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gnav_ephemeris_map", d_ls_pvt->glonass_gnav_ephemeris_map); + LOG(INFO) << "Saved GLONASS GNAV Ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GLONASS GNAV Ephemeris, map is empty"; + } - if (d_ls_pvt->galileo_ephemeris_map.empty() == false) - { - std::ofstream ofs; - try + // Save GPS UTC model parameters + file_name = xml_base_path + "gps_utc_model.xml"; + if (d_ls_pvt->gps_utc_model.valid) { - ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); - boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->galileo_ephemeris_map); - LOG(INFO) << "Saved Galileo E1 Ephemeris map data"; + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_utc_model", d_ls_pvt->gps_utc_model); + LOG(INFO) << "Saved GPS UTC model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } } - catch (const std::exception& e) + else { - LOG(WARNING) << e.what(); + LOG(INFO) << "Failed to save GPS UTC model parameters, not valid data"; } - } - else - { - LOG(WARNING) << "Failed to save Galileo E1 Ephemeris, map is empty"; - } - // save GLONASS GNAV ephemeris to XML file - file_name = "eph_GLONASS_GNAV.xml"; + // Save Galileo UTC model parameters + file_name = xml_base_path + "gal_utc_model.xml"; + if (d_ls_pvt->galileo_utc_model.Delta_tLS_6 != 0.0) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_utc_model", d_ls_pvt->galileo_utc_model); + LOG(INFO) << "Saved Galileo UTC model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save Galileo UTC model parameters, not valid data"; + } - if (d_ls_pvt->glonass_gnav_ephemeris_map.empty() == false) - { - std::ofstream ofs; - try + // Save GPS iono parameters + file_name = xml_base_path + "gps_iono.xml"; + if (d_ls_pvt->gps_iono.valid == true) { - ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); - boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->glonass_gnav_ephemeris_map); - LOG(INFO) << "Saved GLONASS GNAV Ephemeris map data"; + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_iono_model", d_ls_pvt->gps_iono); + LOG(INFO) << "Saved GPS ionospheric model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } } - catch (std::exception& e) + else { - LOG(WARNING) << e.what(); + LOG(INFO) << "Failed to save GPS ionospheric model parameters, not valid data"; + } + + // Save GPS CNAV iono parameters + file_name = xml_base_path + "gps_cnav_iono.xml"; + if (d_ls_pvt->gps_cnav_iono.valid == true) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_cnav_iono_model", d_ls_pvt->gps_cnav_iono); + LOG(INFO) << "Saved GPS CNAV ionospheric model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GPS CNAV ionospheric model parameters, not valid data"; + } + + // Save Galileo iono parameters + file_name = xml_base_path + "gal_iono.xml"; + if (d_ls_pvt->galileo_iono.ai0_5 != 0.0) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_iono_model", d_ls_pvt->galileo_iono); + LOG(INFO) << "Saved Galileo ionospheric model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save Galileo ionospheric model parameters, not valid data"; + } + + // save GPS almanac to XML file + file_name = xml_base_path + "gps_almanac.xml"; + if (d_ls_pvt->gps_almanac_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gps_almanac_map", d_ls_pvt->gps_almanac_map); + LOG(INFO) << "Saved GPS almanac map data"; + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GPS almanac, map is empty"; + } + + // Save Galileo almanac + file_name = xml_base_path + "gal_almanac.xml"; + if (d_ls_pvt->galileo_almanac_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_almanac_map", d_ls_pvt->galileo_almanac_map); + LOG(INFO) << "Saved Galileo almanac data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save Galileo almanac, not valid data"; + } + + // Save GPS CNAV UTC model parameters + file_name = xml_base_path + "gps_cnav_utc_model.xml"; + if (d_ls_pvt->gps_cnav_utc_model.valid) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_cnav_utc_model", d_ls_pvt->gps_cnav_utc_model); + LOG(INFO) << "Saved GPS CNAV UTC model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GPS CNAV UTC model parameters, not valid data"; + } + + // save GLONASS GNAV ephemeris to XML file + file_name = xml_base_path + "glo_gnav_ephemeris.xml"; + if (d_ls_pvt->glonass_gnav_ephemeris_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gnav_ephemeris_map", d_ls_pvt->glonass_gnav_ephemeris_map); + LOG(INFO) << "Saved GLONASS GNAV ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GLONASS GNAV ephemeris, map is empty"; + } + + // save GLONASS UTC model parameters to XML file + file_name = xml_base_path + "glo_utc_model.xml"; + if (d_ls_pvt->glonass_gnav_utc_model.valid) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gnav_utc_model", d_ls_pvt->glonass_gnav_utc_model); + LOG(INFO) << "Saved GLONASS UTC model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GLONASS GNAV ephemeris, not valid data"; } - } - else - { - LOG(WARNING) << "Failed to save GLONASS GNAV Ephemeris, map is empty"; } } @@ -572,9 +885,6 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item bool flag_write_RTCM_MSM_output = false; bool flag_write_RINEX_obs_output = false; bool flag_write_RINEX_nav_output = false; - uint32_t gps_channel = 0; - uint32_t gal_channel = 0; - uint32_t glo_channel = 0; gnss_observables_map.clear(); const Gnss_Synchro** in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer @@ -592,46 +902,49 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item // store valid observables in a map. gnss_observables_map.insert(std::pair(i, in[i][epoch])); } - try + if (b_rtcm_enabled) { - if (d_ls_pvt->gps_ephemeris_map.empty() == false) + try { - if (tmp_eph_iter_gps != d_ls_pvt->gps_ephemeris_map.end()) + if (d_ls_pvt->gps_ephemeris_map.empty() == false) { - d_rtcm_printer->lock_time(d_ls_pvt->gps_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time + if (tmp_eph_iter_gps != d_ls_pvt->gps_ephemeris_map.cend()) + { + d_rtcm_printer->lock_time(d_ls_pvt->gps_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time + } + } + if (d_ls_pvt->galileo_ephemeris_map.empty() == false) + { + if (tmp_eph_iter_gal != d_ls_pvt->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->lock_time(d_ls_pvt->galileo_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time + } + } + if (d_ls_pvt->gps_cnav_ephemeris_map.empty() == false) + { + if (tmp_eph_iter_cnav != d_ls_pvt->gps_cnav_ephemeris_map.cend()) + { + d_rtcm_printer->lock_time(d_ls_pvt->gps_cnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time + } + } + if (d_ls_pvt->glonass_gnav_ephemeris_map.empty() == false) + { + if (tmp_eph_iter_glo_gnav != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->lock_time(d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time + } } } - if (d_ls_pvt->galileo_ephemeris_map.empty() == false) + catch (const boost::exception& ex) { - if (tmp_eph_iter_gal != d_ls_pvt->galileo_ephemeris_map.end()) - { - d_rtcm_printer->lock_time(d_ls_pvt->galileo_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time - } + std::cout << "RTCM boost exception: " << boost::diagnostic_information(ex) << std::endl; + LOG(ERROR) << "RTCM boost exception: " << boost::diagnostic_information(ex); } - if (d_ls_pvt->gps_cnav_ephemeris_map.empty() == false) + catch (const std::exception& ex) { - if (tmp_eph_iter_cnav != d_ls_pvt->gps_cnav_ephemeris_map.end()) - { - d_rtcm_printer->lock_time(d_ls_pvt->gps_cnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time - } + std::cout << "RTCM std exception: " << ex.what() << std::endl; + LOG(ERROR) << "RTCM std exception: " << ex.what(); } - if (d_ls_pvt->glonass_gnav_ephemeris_map.empty() == false) - { - if (tmp_eph_iter_glo_gnav != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - d_rtcm_printer->lock_time(d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time - } - } - } - catch (const boost::exception& ex) - { - std::cout << "RTCM boost exception: " << boost::diagnostic_information(ex) << std::endl; - LOG(ERROR) << "RTCM boost exception: " << boost::diagnostic_information(ex); - } - catch (const std::exception& ex) - { - std::cout << "RTCM std exception: " << ex.what() << std::endl; - LOG(ERROR) << "RTCM std exception: " << ex.what(); } } } @@ -654,14 +967,13 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { // receiver clock correction is disabled to be coherent with the RINEX and RTCM standard // std::cout << TEXT_RED << "(internal) accumulated RX clock offset: " << d_ls_pvt->get_time_offset_s() << "[s]" << TEXT_RESET << std::endl; - // for (std::map::iterator it = gnss_observables_map.begin(); it != gnss_observables_map.end(); ++it) + // for (std::map::iterator it = gnss_observables_map.begin(); it != gnss_observables_map.cend(); ++it) // { // todo: check if it has effect to correct the receiver time for the internal pvt solution // take into account that the RINEX obs with the RX time (integer ms) CAN NOT be corrected to keep the coherence in obs time // it->second.Pseudorange_m = it->second.Pseudorange_m - d_ls_pvt->get_time_offset_s() * GPS_C_m_s; // } - if (d_ls_pvt->get_PVT(gnss_observables_map, false)) { //Optional debug code: export observables snapshot for rtklib unit testing @@ -674,17 +986,26 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { flag_display_pvt = true; } - if (current_RX_time_ms % d_rtcm_MT1019_rate_ms == 0 and d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 + if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - flag_write_RTCM_1019_output = true; + if (current_RX_time_ms % d_rtcm_MT1019_rate_ms == 0) + { + flag_write_RTCM_1019_output = true; + } } - if (current_RX_time_ms % d_rtcm_MT1020_rate_ms == 0 and d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 + if (d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - flag_write_RTCM_1020_output = true; + if (current_RX_time_ms % d_rtcm_MT1020_rate_ms == 0) + { + flag_write_RTCM_1020_output = true; + } } - if (current_RX_time_ms % d_rtcm_MT1045_rate_ms == 0 and d_rtcm_MT1045_rate_ms != 0) + if (d_rtcm_MT1045_rate_ms != 0) { - flag_write_RTCM_1045_output = true; + if (current_RX_time_ms % d_rtcm_MT1045_rate_ms == 0) + { + flag_write_RTCM_1045_output = true; + } } // TODO: RTCM 1077, 1087 and 1097 are not used, so, disable the output rates // if (current_RX_time_ms % d_rtcm_MT1077_rate_ms==0 and d_rtcm_MT1077_rate_ms != 0) @@ -699,19 +1020,26 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item // { // last_RTCM_1097_output_time = current_RX_time; // } - - if (current_RX_time_ms % d_rtcm_MSM_rate_ms == 0 and d_rtcm_MSM_rate_ms != 0) + if (d_rtcm_MSM_rate_ms != 0) { - flag_write_RTCM_MSM_output = true; + if (current_RX_time_ms % d_rtcm_MSM_rate_ms == 0) + { + flag_write_RTCM_MSM_output = true; + } } - if (current_RX_time_ms % static_cast(d_rinexobs_rate_ms) == 0) + if (d_rinexobs_rate_ms != 0) { - flag_write_RINEX_obs_output = true; + if (current_RX_time_ms % static_cast(d_rinexobs_rate_ms) == 0) + { + flag_write_RINEX_obs_output = true; + } } - - if (current_RX_time_ms % static_cast(d_rinexnav_rate_ms) == 0) + if (d_rinexnav_rate_ms != 0) { - flag_write_RINEX_nav_output = true; + if (current_RX_time_ms % static_cast(d_rinexnav_rate_ms) == 0) + { + flag_write_RINEX_nav_output = true; + } } if (first_fix == true) @@ -727,9 +1055,9 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item send_sys_v_ttff_msg(ttff); first_fix = false; } - d_kml_dump->print_position(d_ls_pvt, false); - d_gpx_dump->print_position(d_ls_pvt, false); - d_geojson_printer->print_position(d_ls_pvt, false); + if (d_kml_output_enabled) d_kml_dump->print_position(d_ls_pvt, false); + if (d_gpx_output_enabled) d_gpx_dump->print_position(d_ls_pvt, false); + if (d_geojson_output_enabled) d_geojson_printer->print_position(d_ls_pvt, false); d_nmea_printer->Print_Nmea_Line(d_ls_pvt, false); /* @@ -766,571 +1094,677 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item * 29 | GPS L1 C/A + GLONASS L2 C/A * 30 | Galileo E1B + GLONASS L2 C/A * 31 | GPS L2C + GLONASS L2 C/A + * 32 | GPS L1 C/A + Galileo E1B + GPS L5 + Galileo E5a */ // ####################### RINEX FILES ################# - - std::map::const_iterator galileo_ephemeris_iter; - std::map::const_iterator gps_ephemeris_iter; - std::map::const_iterator gps_cnav_ephemeris_iter; - std::map::const_iterator glonass_gnav_ephemeris_iter; - std::map::const_iterator gnss_observables_iter; - - if (!b_rinex_header_written) // & we have utc data in nav message! + if (b_rinex_output_enabled) { - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); - gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + std::map::const_iterator galileo_ephemeris_iter; + std::map::const_iterator gps_ephemeris_iter; + std::map::const_iterator gps_cnav_ephemeris_iter; + std::map::const_iterator glonass_gnav_ephemeris_iter; + if (!b_rinex_header_written) // & we have utc data in nav message! + { + galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); + glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); - if (type_of_rx == 1) // GPS L1 C/A only - { - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, d_rx_time); - rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 2) // GPS L2C only - { - if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time); - rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 3) // GPS L5 only - { - if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time); - rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 4) // Galileo E1B only - { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time); - rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 5) // Galileo E5a only - { - std::string signal("5X"); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 6) // Galileo E5b only - { - std::string signal("7X"); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 7) // GPS L1 C/A + GPS L2C - { - if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) - { - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time); - rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); - b_rinex_header_written = true; // do not write header anymore - } - } - - if (type_of_rx == 9) // GPS L1 C/A + Galileo E1B - { - if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) - { - std::string gal_signal("1B"); - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gal_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 10) // GPS L1 C/A + Galileo E5a - { - if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) - { - std::string gal_signal("5X"); - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gal_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 11) // GPS L1 C/A + Galileo E5b - { - if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) - { - std::string gal_signal("7X"); - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gal_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 14) // Galileo E1B + Galileo E5a - { - if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) - { - std::string gal_signal("1B 5X"); - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gal_signal); - rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 15) // Galileo E1B + Galileo E5b - { - if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) - { - std::string gal_signal("1B 7X"); - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gal_signal); - rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 23) // GLONASS L1 C/A only - { - std::string signal("1G"); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 24) // GLONASS L2 C/A only - { - std::string signal("2G"); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 25) // GLONASS L1 C/A + GLONASS L2 C/A - { - std::string signal("1G 2G"); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); - b_rinex_header_written = true; // do not write header anymore - } - } - - if (type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) - { - std::string glo_signal("1G"); - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); - if (d_rinex_version == 3) - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - if (d_rinex_version == 2) - { - rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); - } - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) - { - std::string glo_signal("1G"); - std::string gal_signal("1B"); - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal, gal_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 28) // GPS L2C + GLONASS L1 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) - { - std::string glo_signal("1G"); - rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 29) // GPS L1 C/A + GLONASS L2 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) && (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) - { - std::string glo_signal("2G"); - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); - if (d_rinex_version == 3) - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - if (d_rinex_version == 2) - { - rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); - } - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 30) // Galileo E1B + GLONASS L2 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) && (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) - { - std::string glo_signal("2G"); - std::string gal_signal("1B"); - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal, gal_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 31) // GPS L2C + GLONASS L2 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) - { - std::string glo_signal("2G"); - rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - } - if (b_rinex_header_written) // The header is already written, we can now log the navigation message data - { - if (flag_write_RINEX_nav_output) - { if (type_of_rx == 1) // GPS L1 C/A only { - rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); + if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, d_rx_time); + rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); + b_rinex_header_written = true; // do not write header anymore + } } if (type_of_rx == 2) // GPS L2C only { - rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map); + if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) + { + std::string signal("2S"); + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model); + b_rinex_header_written = true; // do not write header anymore + } } if (type_of_rx == 3) // GPS L5 only { - rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map); - } - if ((type_of_rx == 4) or (type_of_rx == 5) or (type_of_rx == 6)) // Galileo - { - rp->log_rinex_nav(rp->navGalFile, d_ls_pvt->galileo_ephemeris_map); - } - if (type_of_rx == 7) // GPS L1 C/A + GPS L2C - { - rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map); - } - if ((type_of_rx == 9) or (type_of_rx == 10) or (type_of_rx == 11)) // GPS L1 C/A + Galileo - { - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->galileo_ephemeris_map); - } - if ((type_of_rx == 14) or (type_of_rx == 15)) // Galileo E1B + Galileo E5a - { - rp->log_rinex_nav(rp->navGalFile, d_ls_pvt->galileo_ephemeris_map); - } - if ((type_of_rx == 23) or (type_of_rx == 24) or (type_of_rx == 25)) // GLONASS L1 C/A, GLONASS L2 C/A - { - rp->log_rinex_nav(rp->navGloFile, d_ls_pvt->glonass_gnav_ephemeris_map); - } - if (type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A - { - if (d_rinex_version == 3) - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); - if (d_rinex_version == 2) + if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) { - rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); - rp->log_rinex_nav(rp->navGloFile, d_ls_pvt->glonass_gnav_ephemeris_map); - } - } - if (type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A - { - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->galileo_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); - } - if (type_of_rx == 28) // GPS L2C + GLONASS L1 C/A - { - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_cnav_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); - } - if (type_of_rx == 29) // GPS L1 C/A + GLONASS L2 C/A - { - if (d_rinex_version == 3) - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); - if (d_rinex_version == 2) - { - rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); - rp->log_rinex_nav(rp->navGloFile, d_ls_pvt->glonass_gnav_ephemeris_map); - } - } - if (type_of_rx == 30) // Galileo E1B + GLONASS L2 C/A - { - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->galileo_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); - } - if (type_of_rx == 31) // GPS L2C + GLONASS L2 C/A - { - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_cnav_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); - } - } - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); - gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); - - // Log observables into the RINEX file - if (flag_write_RINEX_obs_output) - { - if (type_of_rx == 1) // GPS L1 C/A only - { - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); - rp->update_nav_header(rp->navFile, d_ls_pvt->gps_utc_model, d_ls_pvt->gps_iono); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 2) // GPS L2C only - { - if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); - rp->update_nav_header(rp->navFile, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->gps_cnav_iono); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 3) // GPS L5 - { - if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); - rp->update_nav_header(rp->navFile, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->gps_cnav_iono); - b_rinex_header_updated = true; + std::string signal("L5"); + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model); + b_rinex_header_written = true; // do not write header anymore } } if (type_of_rx == 4) // Galileo E1B only { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) + if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1B"); - } - if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - b_rinex_header_updated = true; + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time); + rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore } } if (type_of_rx == 5) // Galileo E5a only { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) + std::string signal("5X"); + if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "5X"); - } - if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - b_rinex_header_updated = true; + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore } } if (type_of_rx == 6) // Galileo E5b only { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) + std::string signal("7X"); + if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "7X"); - } - if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - b_rinex_header_updated = true; + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore } } if (type_of_rx == 7) // GPS L1 C/A + GPS L2C { - if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end())) + if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) { - rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + std::string signal("1C 2S"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); + b_rinex_header_written = true; // do not write header anymore } - if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) + } + if (type_of_rx == 8) // GPS L1 + GPS L5 + { + if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); - rp->update_nav_header(rp->navFile, d_ls_pvt->gps_utc_model, d_ls_pvt->gps_iono); - b_rinex_header_updated = true; + std::string signal("1C L5"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); + b_rinex_header_written = true; // do not write header anymore } } if (type_of_rx == 9) // GPS L1 C/A + Galileo E1B { - if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end())) + if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) { - rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_updated = true; + std::string gal_signal("1B"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore } } - if (type_of_rx == 14) // Galileo E1B + Galileo E5a + if (type_of_rx == 10) // GPS L1 C/A + Galileo E5a { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) + if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1B 5X"); - } - if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - b_rinex_header_updated = true; + std::string gal_signal("5X"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore } } - if (type_of_rx == 15) // Galileo E1B + Galileo E5b + if (type_of_rx == 11) // GPS L1 C/A + Galileo E5b { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) + if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1B 7X"); + std::string gal_signal("7X"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore } - if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) + } + if (type_of_rx == 13) // L5+E5a + { + if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) { - rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - b_rinex_header_updated = true; + std::string gal_signal("5X"); + std::string gps_signal("L5"); + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gps_signal, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + } + if (type_of_rx == 14) // Galileo E1B + Galileo E5a + { + if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) + { + std::string gal_signal("1B 5X"); + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gal_signal); + rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + } + if (type_of_rx == 15) // Galileo E1B + Galileo E5b + { + if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) + { + std::string gal_signal("1B 7X"); + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gal_signal); + rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore } } if (type_of_rx == 23) // GLONASS L1 C/A only { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + std::string signal("1G"); + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1C"); - } - if (!b_rinex_header_updated and (d_ls_pvt->glonass_gnav_utc_model.d_tau_c != 0)) - { - rp->update_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->glonass_gnav_utc_model); - b_rinex_header_updated = true; + rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + b_rinex_header_written = true; // do not write header anymore } } if (type_of_rx == 24) // GLONASS L2 C/A only { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + std::string signal("2G"); + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "2C"); - } - if (!b_rinex_header_updated and (d_ls_pvt->glonass_gnav_utc_model.d_tau_c != 0)) - { - rp->update_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->glonass_gnav_utc_model); - b_rinex_header_updated = true; + rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + b_rinex_header_written = true; // do not write header anymore } } if (type_of_rx == 25) // GLONASS L1 C/A + GLONASS L2 C/A { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + std::string signal("1G 2G"); + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1C 2C"); - } - if (!b_rinex_header_updated and (d_ls_pvt->glonass_gnav_utc_model.d_tau_c != 0)) - { - rp->update_nav_header(rp->navMixFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->glonass_gnav_utc_model); - b_rinex_header_updated = true; + rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + b_rinex_header_written = true; // do not write header anymore } } + if (type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end())) + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) { - rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_updated = true; // do not write header anymore + std::string glo_signal("1G"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); + if (d_rinex_version == 3) + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + if (d_rinex_version == 2) + { + rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + } + b_rinex_header_written = true; // do not write header anymore } } - if (type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A + if (type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) and (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end())) + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_updated = true; // do not write header anymore + std::string glo_signal("1G"); + std::string gal_signal("1B"); + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_written = true; // do not write header anymore } } if (type_of_rx == 28) // GPS L2C + GLONASS L1 C/A { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end())) + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) { - rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_updated = true; // do not write header anymore + std::string glo_signal("1G"); + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_written = true; // do not write header anymore } } if (type_of_rx == 29) // GPS L1 C/A + GLONASS L2 C/A { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) && (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end())) + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) { - rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated && (d_ls_pvt->gps_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_updated = true; // do not write header anymore + std::string glo_signal("2G"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); + if (d_rinex_version == 3) + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + if (d_rinex_version == 2) + { + rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + } + b_rinex_header_written = true; // do not write header anymore } } - if (type_of_rx == 30) // Galileo E1B + GLONASS L2 C/A + if (type_of_rx == 30) // Galileo E1B + GLONASS L2 C/A { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) && (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end())) + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated && (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_updated = true; // do not write header anymore + std::string glo_signal("2G"); + std::string gal_signal("1B"); + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_written = true; // do not write header anymore } } if (type_of_rx == 31) // GPS L2C + GLONASS L2 C/A { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end())) + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) { - rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + std::string glo_signal("2G"); + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_written = true; // do not write header anymore } - if (!b_rinex_header_updated && (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) + } + + if (type_of_rx == 32) // L1+E1+L5+E5a + { + if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) and + (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) and + (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_updated = true; // do not write header anymore + std::string gal_signal("1B 5X"); + std::string gps_signal("1C L5"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gps_signal, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + } + } + + if (b_rinex_header_written) // The header is already written, we can now log the navigation message data + { + if (flag_write_RINEX_nav_output) + { + if (type_of_rx == 1) // GPS L1 C/A only + { + rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); + } + if (type_of_rx == 2) // GPS L2C only + { + rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map); + } + if (type_of_rx == 3) // GPS L5 only + { + rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map); + } + if ((type_of_rx == 4) or (type_of_rx == 5) or (type_of_rx == 6)) // Galileo + { + rp->log_rinex_nav(rp->navGalFile, d_ls_pvt->galileo_ephemeris_map); + } + if (type_of_rx == 7) // GPS L1 C/A + GPS L2C + { + rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map); + } + if (type_of_rx == 8) // L1+L5 + { + rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); + } + if ((type_of_rx == 9) or (type_of_rx == 10) or (type_of_rx == 11)) // GPS L1 C/A + Galileo + { + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->galileo_ephemeris_map); + } + if (type_of_rx == 13) // L5+E5a + { + rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map, d_ls_pvt->galileo_ephemeris_map); + } + if ((type_of_rx == 14) or (type_of_rx == 15)) // Galileo E1B + Galileo E5a + { + rp->log_rinex_nav(rp->navGalFile, d_ls_pvt->galileo_ephemeris_map); + } + if ((type_of_rx == 23) or (type_of_rx == 24) or (type_of_rx == 25)) // GLONASS L1 C/A, GLONASS L2 C/A + { + rp->log_rinex_nav(rp->navGloFile, d_ls_pvt->glonass_gnav_ephemeris_map); + } + if (type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A + { + if (d_rinex_version == 3) + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); + if (d_rinex_version == 2) + { + rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); + rp->log_rinex_nav(rp->navGloFile, d_ls_pvt->glonass_gnav_ephemeris_map); + } + } + if (type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A + { + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->galileo_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); + } + if (type_of_rx == 28) // GPS L2C + GLONASS L1 C/A + { + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_cnav_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); + } + if (type_of_rx == 29) // GPS L1 C/A + GLONASS L2 C/A + { + if (d_rinex_version == 3) + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); + if (d_rinex_version == 2) + { + rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); + rp->log_rinex_nav(rp->navGloFile, d_ls_pvt->glonass_gnav_ephemeris_map); + } + } + if (type_of_rx == 30) // Galileo E1B + GLONASS L2 C/A + { + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->galileo_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); + } + if (type_of_rx == 31) // GPS L2C + GLONASS L2 C/A + { + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_cnav_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); + } + if (type_of_rx == 32) // L1+E1+L5+E5a + { + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->galileo_ephemeris_map); + } + } + galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); + glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + + // Log observables into the RINEX file + if (flag_write_RINEX_obs_output) + { + if (type_of_rx == 1) // GPS L1 C/A only + { + if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); + rp->update_nav_header(rp->navFile, d_ls_pvt->gps_utc_model, d_ls_pvt->gps_iono); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 2) // GPS L2C only + { + if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); + rp->update_nav_header(rp->navFile, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->gps_cnav_iono); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 3) // GPS L5 + { + if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); + rp->update_nav_header(rp->navFile, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->gps_cnav_iono); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 4) // Galileo E1B only + { + if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1B"); + } + if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) + { + rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 5) // Galileo E5a only + { + if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "5X"); + } + if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) + { + rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 6) // Galileo E5b only + { + if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "7X"); + } + if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) + { + rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 7) // GPS L1 C/A + GPS L2C + { + if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); + rp->update_nav_header(rp->navFile, d_ls_pvt->gps_utc_model, d_ls_pvt->gps_iono); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 8) // L1+L5 + { + if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and ((d_ls_pvt->gps_cnav_utc_model.d_A0 != 0) or (d_ls_pvt->gps_utc_model.d_A0 != 0))) + { + if (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); + rp->update_nav_header(rp->navFile, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->gps_cnav_iono); + } + else + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); + rp->update_nav_header(rp->navFile, d_ls_pvt->gps_utc_model, d_ls_pvt->gps_iono); + } + b_rinex_header_updated = true; + } + } + if (type_of_rx == 9) // GPS L1 C/A + Galileo E1B + { + if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 13) // L5+E5a + { + if ((gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0) and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->gps_cnav_iono, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + b_rinex_header_updated = true; // do not write header anymore + } + } + if (type_of_rx == 14) // Galileo E1B + Galileo E5a + { + if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1B 5X"); + } + if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) + { + rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 15) // Galileo E1B + Galileo E5b + { + if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1B 7X"); + } + if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) + { + rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 23) // GLONASS L1 C/A only + { + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1C"); + } + if (!b_rinex_header_updated and (d_ls_pvt->glonass_gnav_utc_model.d_tau_c != 0)) + { + rp->update_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + rp->update_obs_header(rp->obsFile, d_ls_pvt->glonass_gnav_utc_model); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 24) // GLONASS L2 C/A only + { + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "2C"); + } + if (!b_rinex_header_updated and (d_ls_pvt->glonass_gnav_utc_model.d_tau_c != 0)) + { + rp->update_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + rp->update_obs_header(rp->obsFile, d_ls_pvt->glonass_gnav_utc_model); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 25) // GLONASS L1 C/A + GLONASS L2 C/A + { + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1C 2C"); + } + if (!b_rinex_header_updated and (d_ls_pvt->glonass_gnav_utc_model.d_tau_c != 0)) + { + rp->update_nav_header(rp->navMixFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + rp->update_obs_header(rp->obsFile, d_ls_pvt->glonass_gnav_utc_model); + b_rinex_header_updated = true; + } + } + if (type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + } + if (type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + } + if (type_of_rx == 28) // GPS L2C + GLONASS L1 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + } + if (type_of_rx == 29) // GPS L1 C/A + GLONASS L2 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + } + if (type_of_rx == 30) // Galileo E1B + GLONASS L2 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + } + if (type_of_rx == 31) // GPS L2C + GLONASS L2 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + } + if (type_of_rx == 32) // L1+E1+L5+E5a + { + if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and ((d_ls_pvt->gps_cnav_utc_model.d_A0 != 0) or (d_ls_pvt->gps_utc_model.d_A0 != 0)) and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) + { + if (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->gps_cnav_iono, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + } + else + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model); + } + b_rinex_header_updated = true; // do not write header anymore + } } } } @@ -1339,25 +1773,23 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item // ####################### RTCM MESSAGES ################# try { - if (b_rtcm_writing_started) + if (b_rtcm_writing_started and b_rtcm_enabled) { if (type_of_rx == 1) // GPS L1 C/A { if (flag_write_RTCM_1019_output == true) { - for (std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (flag_write_RTCM_MSM_output == true) { - std::map::const_iterator gps_ephemeris_iter; - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); - - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } } @@ -1365,18 +1797,17 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (flag_write_RTCM_1045_output == true) { - for (std::map::const_iterator gal_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(gal_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } if (flag_write_RTCM_MSM_output == true) { - std::map::const_iterator gal_ephemeris_iter; - gal_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); - if (gal_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } } @@ -1384,20 +1815,37 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (flag_write_RTCM_1019_output == true) { - for (std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (flag_write_RTCM_MSM_output == true) { - std::map::const_iterator gps_ephemeris_iter; - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); - std::map::const_iterator gps_cnav_ephemeris_iter; - gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); - if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + std::map::const_iterator gps_cnav_eph_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); + if ((gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) and (gps_cnav_eph_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, gps_cnav_eph_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + } + if (type_of_rx == 8) // L1+L5 + { + if (flag_write_RTCM_1019_output == true) + { + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); + } + } + if (flag_write_RTCM_MSM_output == true) + { + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + std::map::const_iterator gps_cnav_eph_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); + if ((gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) and (gps_cnav_eph_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, gps_cnav_eph_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } } @@ -1405,23 +1853,25 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (flag_write_RTCM_1019_output == true) { - for (gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (flag_write_RTCM_1045_output == true) { - for (galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.begin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end(); galileo_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } if (flag_write_RTCM_MSM_output == true) { - //gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - //galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - uint32_t i = 0; + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + int gps_channel = 0; + int gal_channel = 0; for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { std::string system(&gnss_observables_iter->second.System, 1); @@ -1430,10 +1880,10 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item if (system.compare("G") == 0) { // This is a channel with valid GPS signal - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + gps_eph_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) { - gps_channel = i; + gps_channel = 1; } } } @@ -1441,28 +1891,46 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (system.compare("E") == 0) { - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - gal_channel = i; + gal_channel = 1; } } } - i++; } - if (flag_write_RTCM_MSM_output == true) + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - if (flag_write_RTCM_MSM_output == true) + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + } + if (type_of_rx == 13) // L5+E5a + { + std::map::const_iterator gal_eph_iter; + std::map::const_iterator gps_cnav_eph_iter; + if (flag_write_RTCM_1045_output == true) + { + for (gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); + } + } + gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + gps_cnav_eph_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); + if (flag_write_RTCM_MSM_output == true) + { + if (gps_cnav_eph_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, gps_cnav_eph_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } } @@ -1475,22 +1943,24 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); } } - - std::map::const_iterator glo_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); - - if (glo_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + if (flag_write_RTCM_MSM_output == true) { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glo_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + std::map::const_iterator glo_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + if (glo_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glo_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } } b_rtcm_writing_started = true; } if (type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A { + std::map::const_iterator gps_eph_iter; if (flag_write_RTCM_1019_output == true) { - for (gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (flag_write_RTCM_1020_output == true) @@ -1502,10 +1972,12 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item } if (flag_write_RTCM_MSM_output == true) { - //gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - //galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - uint32_t i = 0; - for (gnss_observables_iter = gnss_observables_map.begin(); gnss_observables_iter != gnss_observables_map.end(); gnss_observables_iter++) + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + int gps_channel = 0; + int glo_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { std::string system(&gnss_observables_iter->second.System, 1); if (gps_channel == 0) @@ -1513,10 +1985,10 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item if (system.compare("G") == 0) { // This is a channel with valid GPS signal - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + gps_eph_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) { - gps_channel = i; + gps_channel = 1; } } } @@ -1524,28 +1996,22 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (system.compare("R") == 0) { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - glo_channel = i; + glo_channel = 1; } } } - i++; } - if (flag_write_RTCM_MSM_output == true) + + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - if (flag_write_RTCM_MSM_output == true) + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) { - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } } @@ -1553,23 +2019,25 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (flag_write_RTCM_1020_output == true) { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_ls_pvt->glonass_gnav_utc_model); } } if (flag_write_RTCM_1045_output == true) { - for (galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); galileo_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } if (flag_write_RTCM_MSM_output == true) { - // gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - // galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - uint32_t i = 0; + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + int gal_channel = 0; + int glo_channel = 0; for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { std::string system(&gnss_observables_iter->second.System, 1); @@ -1578,10 +2046,10 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item if (system.compare("E") == 0) { // This is a channel with valid GPS signal - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - gal_channel = i; + gal_channel = 1; } } } @@ -1589,28 +2057,21 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (system.compare("R") == 0) { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - glo_channel = i; + glo_channel = 1; } } } - i++; } - if (flag_write_RTCM_MSM_output == true) + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - if (flag_write_RTCM_MSM_output == true) + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } } @@ -1618,24 +2079,26 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (flag_write_RTCM_1019_output == true) { - for (gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (flag_write_RTCM_1020_output == true) { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_ls_pvt->glonass_gnav_utc_model); } } if (flag_write_RTCM_MSM_output == true) { - // gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - // galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - uint32_t i = 0; - for (gnss_observables_iter = gnss_observables_map.begin(); gnss_observables_iter != gnss_observables_map.end(); gnss_observables_iter++) + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + int gps_channel = 0; + int glo_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { std::string system(&gnss_observables_iter->second.System, 1); if (gps_channel == 0) @@ -1643,10 +2106,10 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item if (system.compare("G") == 0) { // This is a channel with valid GPS signal - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + gps_eph_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) { - gps_channel = i; + gps_channel = 1; } } } @@ -1654,28 +2117,21 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (system.compare("R") == 0) { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - glo_channel = i; + glo_channel = 1; } } } - i++; } - if (flag_write_RTCM_MSM_output == true) + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - if (flag_write_RTCM_MSM_output == true) + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) { - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } } @@ -1683,23 +2139,25 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (flag_write_RTCM_1020_output == true) { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_ls_pvt->glonass_gnav_utc_model); } } if (flag_write_RTCM_1045_output == true) { - for (galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); galileo_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } if (flag_write_RTCM_MSM_output == true) { - // gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - // galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - uint32_t i = 0; + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + int gal_channel = 0; + int glo_channel = 0; for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { std::string system(&gnss_observables_iter->second.System, 1); @@ -1708,10 +2166,10 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item if (system.compare("E") == 0) { // This is a channel with valid GPS signal - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - gal_channel = i; + gal_channel = 1; } } } @@ -1719,78 +2177,164 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (system.compare("R") == 0) { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - glo_channel = i; + glo_channel = 1; } } } - i++; } - if (flag_write_RTCM_MSM_output == true) + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + } + if (type_of_rx == 32) // L1+E1+L5+E5a + { + if (flag_write_RTCM_1019_output == true) + { + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); + } + } + if (flag_write_RTCM_1045_output == true) + { + for (std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); + } + } + if (flag_write_RTCM_MSM_output == true) + { + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + int gal_channel = 0; + int gps_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + { + std::string system(&gnss_observables_iter->second.System, 1); + if (gal_channel == 0) { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + if (system.compare("E") == 0) + { + // This is a channel with valid GPS signal + gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + gal_channel = 1; + } + } + } + if (gps_channel == 0) + { + if (system.compare("G") == 0) + { + gps_eph_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + gps_channel = 1; + } + } } } - if (flag_write_RTCM_MSM_output == true) + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } } } - if (!b_rtcm_writing_started) // the first time + if (!b_rtcm_writing_started and b_rtcm_enabled) // the first time { if (type_of_rx == 1) // GPS L1 C/A { - for (std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); + } } - - std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); - - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + if (d_rtcm_MSM_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } } b_rtcm_writing_started = true; } if ((type_of_rx == 4) || (type_of_rx == 5) || (type_of_rx == 6) || (type_of_rx == 14) || (type_of_rx == 15)) // Galileo { - for (std::map::const_iterator gal_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_ephemeris_iter++) + if (d_rtcm_MT1045_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - d_rtcm_printer->Print_Rtcm_MT1045(gal_ephemeris_iter->second); + for (std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); + } } - - std::map::const_iterator gal_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); - - if (gal_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + if (d_rtcm_MSM_rate_ms != 0) { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } } b_rtcm_writing_started = true; } if (type_of_rx == 7) // GPS L1 C/A + GPS L2C { - for (std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); + } } - - std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); - std::map::const_iterator gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); - - if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) + if (d_rtcm_MSM_rate_ms != 0) { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + std::map::const_iterator gps_cnav_eph_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); + if ((gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) and (gps_cnav_eph_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, gps_cnav_eph_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + b_rtcm_writing_started = true; + } + if (type_of_rx == 8) // L1+L5 + { + if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); + } + } + if (d_rtcm_MSM_rate_ms != 0) + { + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + std::map::const_iterator gps_cnav_eph_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); + if ((gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) and (gps_cnav_eph_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, gps_cnav_eph_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } } b_rtcm_writing_started = true; } @@ -1798,72 +2342,99 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (d_rtcm_MT1045_rate_ms != 0) { - for (galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.begin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end(); galileo_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } - - uint32_t i = 0; - for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + if (d_rtcm_MSM_rate_ms != 0) { - std::string system(&gnss_observables_iter->second.System, 1); - if (gps_channel == 0) + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + int gps_channel = 0; + int gal_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { - if (system.compare("G") == 0) + std::string system(&gnss_observables_iter->second.System, 1); + if (gps_channel == 0) { - // This is a channel with valid GPS signal - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) + if (system.compare("G") == 0) { - gps_channel = i; + // This is a channel with valid GPS signal + gps_eph_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + gps_channel = 1; + } + } + } + if (gal_channel == 0) + { + if (system.compare("E") == 0) + { + gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + gal_channel = 1; + } } } } - if (gal_channel == 0) + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) { - if (system.compare("E") == 0) - { - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - gal_channel = i; - } - } + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - i++; - } - - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end() && (d_rtcm_MT1077_rate_ms != 0)) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end() && (d_rtcm_MT1097_rate_ms != 0)) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } b_rtcm_writing_started = true; } if ((type_of_rx == 23) || (type_of_rx == 24) || (type_of_rx == 25)) // GLONASS { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + if (d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + for (std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_ls_pvt->glonass_gnav_utc_model); + } } - - std::map::const_iterator glo_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); - - if (glo_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + if (d_rtcm_MSM_rate_ms != 0) { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glo_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + std::map::const_iterator glo_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + if (glo_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glo_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + b_rtcm_writing_started = true; + } + if (type_of_rx == 13) // L5+E5a + { + std::map::const_iterator gal_eph_iter; + if (d_rtcm_MT1045_rate_ms != 0) + { + for (gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); + } + } + if (d_rtcm_MSM_rate_ms != 0) + { + gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend() and (d_rtcm_MT1097_rate_ms != 0)) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } } b_rtcm_writing_started = true; } @@ -1871,235 +2442,310 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_ls_pvt->glonass_gnav_utc_model); } } - - // gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - // galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - uint32_t i = 0; - for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + if (d_rtcm_MSM_rate_ms != 0) { - std::string system(&gnss_observables_iter->second.System, 1); - if (gps_channel == 0) + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + int gps_channel = 0; + int glo_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { - if (system.compare("G") == 0) + std::string system(&gnss_observables_iter->second.System, 1); + if (gps_channel == 0) { - // This is a channel with valid GPS signal - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + if (system.compare("G") == 0) { - gps_channel = i; + // This is a channel with valid GPS signal + gps_eph_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + gps_channel = 1; + } + } + } + if (glo_channel == 0) + { + if (system.compare("R") == 0) + { + glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + glo_channel = 1; + } } } } - if (glo_channel == 0) + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - if (system.compare("R") == 0) - { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - glo_channel = i; - } - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - i++; } - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - b_rtcm_writing_started = true; } if (type_of_rx == 27) // GLONASS L1 C/A + Galileo E1B { if (d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_ls_pvt->glonass_gnav_utc_model); } } if (d_rtcm_MT1045_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); galileo_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } - - uint32_t i = 0; - for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + if (d_rtcm_MSM_rate_ms != 0) { - std::string system(&gnss_observables_iter->second.System, 1); - if (gal_channel == 0) + int gal_channel = 0; + int glo_channel = 0; + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { - if (system.compare("E") == 0) + std::string system(&gnss_observables_iter->second.System, 1); + if (gal_channel == 0) { - // This is a channel with valid GPS signal - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + if (system.compare("E") == 0) { - gal_channel = i; + // This is a channel with valid GPS signal + gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + gal_channel = 1; + } + } + } + if (glo_channel == 0) + { + if (system.compare("R") == 0) + { + glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + glo_channel = 1; + } } } } - if (glo_channel == 0) + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - if (system.compare("R") == 0) - { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - glo_channel = i; - } - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - i++; - } - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } + b_rtcm_writing_started = true; } if (type_of_rx == 29) // GPS L1 C/A + GLONASS L2 C/A { if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_ls_pvt->glonass_gnav_utc_model); } } - - // gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - // galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - uint32_t i = 0; - for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + if (d_rtcm_MSM_rate_ms != 0) { - std::string system(&gnss_observables_iter->second.System, 1); - if (gps_channel == 0) + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + std::map::const_iterator gnss_observables_iter; + int gps_channel = 0; + int glo_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { - if (system.compare("G") == 0) + std::string system(&gnss_observables_iter->second.System, 1); + if (gps_channel == 0) { - // This is a channel with valid GPS signal - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + if (system.compare("G") == 0) { - gps_channel = i; + // This is a channel with valid GPS signal + gps_eph_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + gps_channel = 1; + } + } + } + if (glo_channel == 0) + { + if (system.compare("R") == 0) + { + glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + glo_channel = 1; + } } } } - if (glo_channel == 0) + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - if (system.compare("R") == 0) - { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - glo_channel = i; - } - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - i++; - } - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } } - b_rtcm_writing_started = true; } if (type_of_rx == 30) // GLONASS L2 C/A + Galileo E1B { if (d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_ls_pvt->glonass_gnav_utc_model); } } if (d_rtcm_MT1045_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); galileo_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } - - uint32_t i = 0; - for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + if (d_rtcm_MSM_rate_ms != 0) { - std::string system(&gnss_observables_iter->second.System, 1); - if (gal_channel == 0) + int gal_channel = 0; + int glo_channel = 0; + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { - if (system.compare("E") == 0) + std::string system(&gnss_observables_iter->second.System, 1); + if (gal_channel == 0) { - // This is a channel with valid GPS signal - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + if (system.compare("E") == 0) { - gal_channel = i; + // This is a channel with valid GPS signal + gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + gal_channel = 1; + } + } + } + if (glo_channel == 0) + { + if (system.compare("R") == 0) + { + glonass_gnav_eph_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + glo_channel = 1; + } } } } - if (glo_channel == 0) + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - if (system.compare("R") == 0) + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (glonass_gnav_eph_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + b_rtcm_writing_started = true; + } + if (type_of_rx == 32) // L1+E1+L5+E5a + { + if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for (std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); + } + } + if (d_rtcm_MT1045_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for (std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); + } + } + if (d_rtcm_MSM_rate_ms != 0) + { + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); + std::map::const_iterator gps_eph_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); + int gps_channel = 0; + int gal_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + { + std::string system(&gnss_observables_iter->second.System, 1); + if (gps_channel == 0) { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + if (system.compare("G") == 0) { - glo_channel = i; + // This is a channel with valid GPS signal + gps_eph_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + gps_channel = 1; + } + } + } + if (gal_channel == 0) + { + if (system.compare("E") == 0) + { + gal_eph_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + gal_channel = 1; + } } } } - i++; - } - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + if (gps_eph_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (gal_eph_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } } + b_rtcm_writing_started = true; } } } - catch (const boost::exception& ex) { std::cout << "RTCM boost exception: " << boost::diagnostic_information(ex) << std::endl; diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h index 3dfb87858..427936704 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h @@ -38,6 +38,7 @@ #include "geojson_printer.h" #include "rinex_printer.h" #include "rtcm_printer.h" +#include "pvt_conf.h" #include "rtklib_solver.h" #include #include @@ -55,23 +56,7 @@ class rtklib_pvt_cc; typedef boost::shared_ptr rtklib_pvt_cc_sptr; rtklib_pvt_cc_sptr rtklib_make_pvt_cc(uint32_t n_channels, - bool dump, - std::string dump_filename, - int32_t output_rate_ms, - int32_t display_rate_ms, - bool flag_nmea_tty_port, - std::string nmea_dump_filename, - std::string nmea_dump_devname, - int32_t rinex_version, - int32_t rinexobs_rate_ms, - int32_t rinexnav_rate_ms, - bool flag_rtcm_server, - bool flag_rtcm_tty_port, - uint16_t rtcm_tcp_port, - uint16_t rtcm_station_id, - std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname, - const uint32_t type_of_receiver, + const Pvt_Conf& conf_, rtk_t& rtk); /*! @@ -81,28 +66,14 @@ class rtklib_pvt_cc : public gr::sync_block { private: friend rtklib_pvt_cc_sptr rtklib_make_pvt_cc(uint32_t nchannels, - bool dump, - std::string dump_filename, - int32_t output_rate_ms, - int32_t display_rate_ms, - bool flag_nmea_tty_port, - std::string nmea_dump_filename, - std::string nmea_dump_devname, - int32_t rinex_version, - int32_t rinexobs_rate_ms, - int32_t rinexnav_rate_ms, - bool flag_rtcm_server, - bool flag_rtcm_tty_port, - uint16_t rtcm_tcp_port, - uint16_t rtcm_station_id, - std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname, - const uint32_t type_of_receiver, + const Pvt_Conf& conf_, rtk_t& rtk); void msg_handler_telemetry(pmt::pmt_t msg); bool d_dump; + bool d_dump_mat; + bool b_rinex_output_enabled; bool b_rinex_header_written; bool b_rinex_header_updated; double d_rinex_version; @@ -110,6 +81,7 @@ private: int32_t d_rinexnav_rate_ms; bool b_rtcm_writing_started; + bool b_rtcm_enabled; int32_t d_rtcm_MT1045_rate_ms; //!< Galileo Broadcast Ephemeris int32_t d_rtcm_MT1019_rate_ms; //!< GPS Broadcast Ephemeris (orbits) int32_t d_rtcm_MT1020_rate_ms; //!< GLONASS Broadcast Ephemeris (orbits) @@ -134,6 +106,10 @@ private: std::shared_ptr d_rtcm_printer; double d_rx_time; + bool d_geojson_output_enabled; + bool d_gpx_output_enabled; + bool d_kml_output_enabled; + std::shared_ptr d_ls_pvt; std::map gnss_observables_map; @@ -156,24 +132,13 @@ private: bool load_gnss_synchro_map_xml(const std::string file_name); //debug helper function + bool d_xml_storage; + std::string xml_base_path; + + public: rtklib_pvt_cc(uint32_t nchannels, - bool dump, std::string dump_filename, - int32_t output_rate_ms, - int32_t display_rate_ms, - bool flag_nmea_tty_port, - std::string nmea_dump_filename, - std::string nmea_dump_devname, - int32_t rinex_version, - int32_t rinexobs_rate_ms, - int32_t rinexnav_rate_ms, - bool flag_rtcm_server, - bool flag_rtcm_tty_port, - uint16_t rtcm_tcp_port, - uint16_t rtcm_station_id, - std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname, - const uint32_t type_of_receiver, + const Pvt_Conf& conf_, rtk_t& rtk); /*! diff --git a/src/algorithms/PVT/libs/CMakeLists.txt b/src/algorithms/PVT/libs/CMakeLists.txt index caf02a4ce..6807e9602 100644 --- a/src/algorithms/PVT/libs/CMakeLists.txt +++ b/src/algorithms/PVT/libs/CMakeLists.txt @@ -29,6 +29,7 @@ set(PVT_LIB_SOURCES rtcm_printer.cc geojson_printer.cc rtklib_solver.cc + pvt_conf.cc ) set(PVT_LIB_HEADERS @@ -42,6 +43,7 @@ set(PVT_LIB_HEADERS rtcm_printer.h geojson_printer.h rtklib_solver.h + pvt_conf.h ) @@ -57,6 +59,7 @@ include_directories( ${ARMADILLO_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS} ${GLOG_INCLUDE_DIRS} + ${MATIO_INCLUDE_DIRS} ) list(SORT PVT_LIB_HEADERS) @@ -64,7 +67,12 @@ list(SORT PVT_LIB_SOURCES) add_library(pvt_lib ${PVT_LIB_SOURCES} ${PVT_LIB_HEADERS}) source_group(Headers FILES ${PVT_LIB_HEADERS}) -add_dependencies(pvt_lib rtklib_lib armadillo-${armadillo_RELEASE} glog-${glog_RELEASE}) + +if(MATIO_FOUND) + add_dependencies(pvt_lib glog-${glog_RELEASE} armadillo-${armadillo_RELEASE}) +else(MATIO_FOUND) + add_dependencies(pvt_lib glog-${glog_RELEASE} armadillo-${armadillo_RELEASE} matio-${GNSSSDR_MATIO_LOCAL_VERSION}) +endif(MATIO_FOUND) target_link_libraries( pvt_lib @@ -75,4 +83,5 @@ target_link_libraries( ${ARMADILLO_LIBRARIES} ${BLAS} ${LAPACK} + ${MATIO_LIBRARIES} ) diff --git a/src/algorithms/PVT/libs/geojson_printer.cc b/src/algorithms/PVT/libs/geojson_printer.cc index 5dd3ecdba..b79a4edae 100644 --- a/src/algorithms/PVT/libs/geojson_printer.cc +++ b/src/algorithms/PVT/libs/geojson_printer.cc @@ -32,14 +32,48 @@ #include "geojson_printer.h" #include +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem #include #include #include -GeoJSON_Printer::GeoJSON_Printer() +GeoJSON_Printer::GeoJSON_Printer(const std::string& base_path) { first_pos = true; + geojson_base_path = base_path; + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(geojson_base_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(geojson_base_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + geojson_base_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + geojson_base_path = p.string(); + } + if (geojson_base_path.compare(".") != 0) + { + std::cout << "GeoJSON files will be stored at " << geojson_base_path << std::endl; + } + + geojson_base_path = geojson_base_path + boost::filesystem::path::preferred_separator; } @@ -96,6 +130,7 @@ bool GeoJSON_Printer::set_headers(std::string filename, bool time_tag_name) { filename_ = filename + ".geojson"; } + filename_ = geojson_base_path + filename_; geojson_file.open(filename_.c_str()); @@ -124,6 +159,7 @@ bool GeoJSON_Printer::set_headers(std::string filename, bool time_tag_name) } else { + std::cout << "File " << filename_ << " cannot be saved. Wrong permissions?" << std::endl; return false; } } diff --git a/src/algorithms/PVT/libs/geojson_printer.h b/src/algorithms/PVT/libs/geojson_printer.h index 9963e64d2..63630552c 100644 --- a/src/algorithms/PVT/libs/geojson_printer.h +++ b/src/algorithms/PVT/libs/geojson_printer.h @@ -50,9 +50,10 @@ private: std::ofstream geojson_file; bool first_pos; std::string filename_; + std::string geojson_base_path; public: - GeoJSON_Printer(); + GeoJSON_Printer(const std::string& base_path = "."); ~GeoJSON_Printer(); bool set_headers(std::string filename, bool time_tag_name = true); bool print_position(const std::shared_ptr& position, bool print_average_values); diff --git a/src/algorithms/PVT/libs/gpx_printer.cc b/src/algorithms/PVT/libs/gpx_printer.cc index 51fa6760f..f0b4b3ff3 100644 --- a/src/algorithms/PVT/libs/gpx_printer.cc +++ b/src/algorithms/PVT/libs/gpx_printer.cc @@ -32,11 +32,53 @@ #include "gpx_printer.h" #include +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem #include #include using google::LogMessage; + +Gpx_Printer::Gpx_Printer(const std::string& base_path) +{ + positions_printed = false; + indent = " "; + gpx_base_path = base_path; + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(gpx_base_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(gpx_base_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + gpx_base_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + gpx_base_path = p.string(); + } + if (gpx_base_path.compare(".") != 0) + { + std::cout << "GPX files will be stored at " << gpx_base_path << std::endl; + } + + gpx_base_path = gpx_base_path + boost::filesystem::path::preferred_separator; +} + + bool Gpx_Printer::set_headers(std::string filename, bool time_tag_name) { boost::posix_time::ptime pt = boost::posix_time::second_clock::local_time(); @@ -84,6 +126,8 @@ bool Gpx_Printer::set_headers(std::string filename, bool time_tag_name) { gpx_filename = filename + ".gpx"; } + + gpx_filename = gpx_base_path + gpx_filename; gpx_file.open(gpx_filename.c_str()); if (gpx_file.is_open()) @@ -105,6 +149,7 @@ bool Gpx_Printer::set_headers(std::string filename, bool time_tag_name) } else { + std::cout << "File " << gpx_filename << " cannot be saved. Wrong permissions?" << std::endl; return false; } } @@ -171,13 +216,6 @@ bool Gpx_Printer::close_file() } -Gpx_Printer::Gpx_Printer() -{ - positions_printed = false; - indent = " "; -} - - Gpx_Printer::~Gpx_Printer() { close_file(); diff --git a/src/algorithms/PVT/libs/gpx_printer.h b/src/algorithms/PVT/libs/gpx_printer.h index f158b6fb9..d4efcf81d 100644 --- a/src/algorithms/PVT/libs/gpx_printer.h +++ b/src/algorithms/PVT/libs/gpx_printer.h @@ -52,9 +52,10 @@ private: bool positions_printed; std::string gpx_filename; std::string indent; + std::string gpx_base_path; public: - Gpx_Printer(); + Gpx_Printer(const std::string& base_path = "."); ~Gpx_Printer(); bool set_headers(std::string filename, bool time_tag_name = true); bool print_position(const std::shared_ptr& position, bool print_average_values); diff --git a/src/algorithms/PVT/libs/hybrid_ls_pvt.h b/src/algorithms/PVT/libs/hybrid_ls_pvt.h index f8a6fc32c..2fe5fd9f3 100644 --- a/src/algorithms/PVT/libs/hybrid_ls_pvt.h +++ b/src/algorithms/PVT/libs/hybrid_ls_pvt.h @@ -36,6 +36,7 @@ #include "galileo_navigation_message.h" #include "gps_navigation_message.h" #include "gps_cnav_navigation_message.h" +#include "galileo_almanac.h" #include "gnss_synchro.h" #include "rtklib_rtkcmn.h" #include diff --git a/src/algorithms/PVT/libs/kml_printer.cc b/src/algorithms/PVT/libs/kml_printer.cc index 1233df036..4ebfcb970 100644 --- a/src/algorithms/PVT/libs/kml_printer.cc +++ b/src/algorithms/PVT/libs/kml_printer.cc @@ -31,11 +31,52 @@ #include "kml_printer.h" #include +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem #include #include using google::LogMessage; + +Kml_Printer::Kml_Printer(const std::string& base_path) +{ + positions_printed = false; + kml_base_path = base_path; + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(kml_base_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(kml_base_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + kml_base_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + kml_base_path = p.string(); + } + if (kml_base_path.compare(".") != 0) + { + std::cout << "KML files will be stored at " << kml_base_path << std::endl; + } + + kml_base_path = kml_base_path + boost::filesystem::path::preferred_separator; +} + + bool Kml_Printer::set_headers(std::string filename, bool time_tag_name) { boost::posix_time::ptime pt = boost::posix_time::second_clock::local_time(); @@ -83,6 +124,7 @@ bool Kml_Printer::set_headers(std::string filename, bool time_tag_name) { kml_filename = filename + ".kml"; } + kml_filename = kml_base_path + kml_filename; kml_file.open(kml_filename.c_str()); if (kml_file.is_open()) @@ -119,6 +161,7 @@ bool Kml_Printer::set_headers(std::string filename, bool time_tag_name) } else { + std::cout << "File " << kml_filename << " cannot be saved. Wrong permissions?" << std::endl; return false; } } @@ -178,12 +221,6 @@ bool Kml_Printer::close_file() } -Kml_Printer::Kml_Printer() -{ - positions_printed = false; -} - - Kml_Printer::~Kml_Printer() { close_file(); diff --git a/src/algorithms/PVT/libs/kml_printer.h b/src/algorithms/PVT/libs/kml_printer.h index 435943a6c..9aed7c02c 100644 --- a/src/algorithms/PVT/libs/kml_printer.h +++ b/src/algorithms/PVT/libs/kml_printer.h @@ -50,9 +50,10 @@ private: std::ofstream kml_file; bool positions_printed; std::string kml_filename; + std::string kml_base_path; public: - Kml_Printer(); + Kml_Printer(const std::string& base_path = std::string(".")); ~Kml_Printer(); bool set_headers(std::string filename, bool time_tag_name = true); bool print_position(const std::shared_ptr& position, bool print_average_values); diff --git a/src/algorithms/PVT/libs/nmea_printer.cc b/src/algorithms/PVT/libs/nmea_printer.cc index c9c1e8052..1337526b9 100644 --- a/src/algorithms/PVT/libs/nmea_printer.cc +++ b/src/algorithms/PVT/libs/nmea_printer.cc @@ -35,6 +35,9 @@ #include "nmea_printer.h" #include +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem #include #include #include @@ -44,13 +47,55 @@ using google::LogMessage; -Nmea_Printer::Nmea_Printer(std::string filename, bool flag_nmea_tty_port, std::string nmea_dump_devname) +Nmea_Printer::Nmea_Printer(std::string filename, bool flag_nmea_output_file, bool flag_nmea_tty_port, std::string nmea_dump_devname, const std::string& base_path) { - nmea_filename = filename; - nmea_file_descriptor.open(nmea_filename.c_str(), std::ios::out); - if (nmea_file_descriptor.is_open()) + nmea_base_path = base_path; + d_flag_nmea_output_file = flag_nmea_output_file; + if (d_flag_nmea_output_file == true) { - DLOG(INFO) << "NMEA printer writing on " << nmea_filename.c_str(); + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(nmea_base_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(nmea_base_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + nmea_base_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + nmea_base_path = p.string(); + } + + if ((nmea_base_path.compare(".") != 0) and (d_flag_nmea_output_file == true)) + { + std::cout << "NMEA files will be stored at " << nmea_base_path << std::endl; + } + + nmea_base_path = nmea_base_path + boost::filesystem::path::preferred_separator; + + nmea_filename = nmea_base_path + filename; + + nmea_file_descriptor.open(nmea_filename.c_str(), std::ios::out); + if (nmea_file_descriptor.is_open()) + { + DLOG(INFO) << "NMEA printer writing on " << nmea_filename.c_str(); + } + else + { + std::cout << "File " << nmea_filename << " cannot be saved. Wrong permissions?" << std::endl; + } } nmea_devname = nmea_dump_devname; @@ -94,13 +139,13 @@ int Nmea_Printer::init_serial(std::string serial_device) int64_t PARITY; fd = open(serial_device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); - if (fd == -1) return fd; //failed to open TTY port + if (fd == -1) return fd; // failed to open TTY port if (fcntl(fd, F_SETFL, 0) == -1) LOG(INFO) << "Error enabling direct I/O"; // clear all flags on descriptor, enable direct I/O tcgetattr(fd, &options); // read serial port options BAUD = B9600; - //BAUD = B38400; + // BAUD = B38400; DATABITS = CS8; STOPBITS = 0; PARITYON = 0; @@ -108,7 +153,7 @@ int Nmea_Printer::init_serial(std::string serial_device) options.c_cflag = BAUD | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD; // enable receiver, set 8 bit data, ignore control lines - //options.c_cflag |= (CLOCAL | CREAD | CS8); + // options.c_cflag |= (CLOCAL | CREAD | CS8); options.c_iflag = IGNPAR; // set the new port options @@ -139,34 +184,36 @@ bool Nmea_Printer::Print_Nmea_Line(const std::shared_ptr& pvt_dat // generate the NMEA sentences - //GPRMC + // GPRMC GPRMC = get_GPRMC(); - //GPGGA (Global Positioning System Fixed Data) + // GPGGA (Global Positioning System Fixed Data) GPGGA = get_GPGGA(); - //GPGSA + // GPGSA GPGSA = get_GPGSA(); - //GPGSV + // GPGSV GPGSV = get_GPGSV(); // write to log file - try + if (d_flag_nmea_output_file) { - //GPRMC - nmea_file_descriptor << GPRMC; - //GPGGA (Global Positioning System Fixed Data) - nmea_file_descriptor << GPGGA; - //GPGSA - nmea_file_descriptor << GPGSA; - //GPGSV - nmea_file_descriptor << GPGSV; - } - catch (const std::exception& ex) - { - DLOG(INFO) << "NMEA printer can not write on output file" << nmea_filename.c_str(); - ; + try + { + // GPRMC + nmea_file_descriptor << GPRMC; + // GPGGA (Global Positioning System Fixed Data) + nmea_file_descriptor << GPGGA; + // GPGSA + nmea_file_descriptor << GPGSA; + // GPGSV + nmea_file_descriptor << GPGSV; + } + catch (const std::exception& ex) + { + DLOG(INFO) << "NMEA printer can not write on output file" << nmea_filename.c_str(); + } } - //write to serial device + // write to serial device if (nmea_dev_descriptor != -1) { if (write(nmea_dev_descriptor, GPRMC.c_str(), GPRMC.length()) == -1) @@ -284,7 +331,7 @@ std::string Nmea_Printer::longitude_to_hm(double longitude) std::string Nmea_Printer::get_UTC_NMEA_time(boost::posix_time::ptime d_position_UTC_time) { - //UTC Time: hhmmss.sss + // UTC Time: hhmmss.sss std::stringstream sentence_str; boost::posix_time::time_duration td = d_position_UTC_time.time_of_day(); @@ -335,20 +382,19 @@ std::string Nmea_Printer::get_GPRMC() double speed_over_ground_knots = 0; double course_over_ground_deg = 0; - //boost::posix_time::ptime d_position_UTC_time=boost::posix_time::microsec_clock::universal_time(); + // boost::posix_time::ptime d_position_UTC_time=boost::posix_time::microsec_clock::universal_time(); std::stringstream sentence_str; - //GPRMC (RMC-Recommended,Minimum Specific GNSS Data) + // GPRMC (RMC-Recommended,Minimum Specific GNSS Data) std::string sentence_header; sentence_header = "$GPRMC,"; sentence_str << sentence_header; - //UTC Time: hhmmss.sss + // UTC Time: hhmmss.sss sentence_str << get_UTC_NMEA_time(d_PVT_data->get_position_UTC_time()); - //Status: A: data valid, V: data NOT valid - + // Status: A: data valid, V: data NOT valid if (valid_fix == true) { sentence_str << ",A"; @@ -373,13 +419,13 @@ std::string Nmea_Printer::get_GPRMC() sentence_str << "," << longitude_to_hm(d_PVT_data->get_longitude()); } - //Speed over ground (knots) + // Speed over ground (knots) sentence_str << ","; sentence_str.setf(std::ios::fixed, std::ios::floatfield); sentence_str.precision(2); sentence_str << speed_over_ground_knots; - //course over ground (degrees) + // course over ground (degrees) sentence_str << ","; sentence_str.setf(std::ios::fixed, std::ios::floatfield); sentence_str.precision(2); @@ -403,11 +449,11 @@ std::string Nmea_Printer::get_GPRMC() year_strs << std::dec << year; sentence_str << std::dec << year_strs.str().substr(2); - //Magnetic Variation (degrees) + // Magnetic Variation (degrees) // ToDo: Implement magnetic compass sentence_str << ","; - //Magnetic Variation (E or W) + // Magnetic Variation (E or W) // ToDo: Implement magnetic compass sentence_str << ","; @@ -429,7 +475,7 @@ std::string Nmea_Printer::get_GPRMC() std::string Nmea_Printer::get_GPGSA() { - //$GPGSA,A,3,07,02,26,27,09,04,15, , , , , ,1.8,1.0,1.5*33 + // $GPGSA,A,3,07,02,26,27,09,04,15, , , , , ,1.8,1.0,1.5*33 // GSA-GNSS DOP and Active Satellites bool valid_fix = d_PVT_data->is_valid_position(); int n_sats_used = d_PVT_data->get_num_valid_observations(); @@ -480,14 +526,14 @@ std::string Nmea_Printer::get_GPGSA() sentence_str.precision(1); sentence_str.fill('0'); sentence_str << pdop; - //HDOP + // HDOP sentence_str << ","; sentence_str.setf(std::ios::fixed, std::ios::floatfield); sentence_str.width(2); sentence_str.precision(1); sentence_str.fill('0'); sentence_str << hdop; - //VDOP + // VDOP sentence_str << ","; sentence_str.setf(std::ios::fixed, std::ios::floatfield); sentence_str.width(2); @@ -548,7 +594,7 @@ std::string Nmea_Printer::get_GPGSV() frame_str.fill('0'); frame_str << std::dec << n_sats_used; - //satellites info + // satellites info for (int j = 0; j < 4; j++) { // write satellite info @@ -595,13 +641,13 @@ std::string Nmea_Printer::get_GPGSV() sentence_str << frame_str.str(); } return sentence_str.str(); - //$GPGSV,2,1,07,07,79,048,42,02,51,062,43,26,36,256,42,27,27,138,42*71 + // $GPGSV,2,1,07,07,79,048,42,02,51,062,43,26,36,256,42,27,27,138,42*71 } std::string Nmea_Printer::get_GPGGA() { - //boost::posix_time::ptime d_position_UTC_time=boost::posix_time::microsec_clock::universal_time(); + // boost::posix_time::ptime d_position_UTC_time=boost::posix_time::microsec_clock::universal_time(); bool valid_fix = d_PVT_data->is_valid_position(); int n_channels = d_PVT_data->get_num_valid_observations(); //d_nchannels double hdop = d_PVT_data->get_hdop(); @@ -618,12 +664,12 @@ std::string Nmea_Printer::get_GPGGA() std::stringstream sentence_str; - //GPGGA (Global Positioning System Fixed Data) + // GPGGA (Global Positioning System Fixed Data) std::string sentence_header; sentence_header = "$GPGGA,"; sentence_str << sentence_header; - //UTC Time: hhmmss.sss + // UTC Time: hhmmss.sss sentence_str << get_UTC_NMEA_time(d_PVT_data->get_position_UTC_time()); if (d_PVT_data->is_averaging() == true) @@ -708,5 +754,5 @@ std::string Nmea_Printer::get_GPGGA() // end NMEA sentence sentence_str << "\r\n"; return sentence_str.str(); - //$GPGGA,104427.591,5920.7009,N,01803.2938,E,1,05,3.3,78.2,M,23.2,M,0.0,0000*4A + // $GPGGA,104427.591,5920.7009,N,01803.2938,E,1,05,3.3,78.2,M,23.2,M,0.0,0000*4A } diff --git a/src/algorithms/PVT/libs/nmea_printer.h b/src/algorithms/PVT/libs/nmea_printer.h index 318745e1c..b2f961756 100644 --- a/src/algorithms/PVT/libs/nmea_printer.h +++ b/src/algorithms/PVT/libs/nmea_printer.h @@ -53,7 +53,7 @@ public: /*! * \brief Default constructor. */ - Nmea_Printer(std::string filename, bool flag_nmea_tty_port, std::string nmea_dump_filename); + Nmea_Printer(std::string filename, bool flag_nmea_output_file, bool flag_nmea_tty_port, std::string nmea_dump_filename, const std::string& base_path = "."); /*! * \brief Print NMEA PVT and satellite info to the initialized device @@ -66,7 +66,8 @@ public: ~Nmea_Printer(); private: - std::string nmea_filename; // String with the NMEA log filename + std::string nmea_filename; // String with the NMEA log filename + std::string nmea_base_path; std::ofstream nmea_file_descriptor; // Output file stream for NMEA log file std::string nmea_devname; int nmea_dev_descriptor; // NMEA serial device descriptor (i.e. COM port) @@ -82,6 +83,7 @@ private: std::string latitude_to_hm(double lat); char checkSum(std::string sentence); bool print_avg_pos; + bool d_flag_nmea_output_file; }; #endif diff --git a/src/algorithms/PVT/libs/pvt_conf.cc b/src/algorithms/PVT/libs/pvt_conf.cc new file mode 100644 index 000000000..0f528f438 --- /dev/null +++ b/src/algorithms/PVT/libs/pvt_conf.cc @@ -0,0 +1,70 @@ +/*! + * \file pvt_conf.cc + * \brief Class that contains all the configuration parameters for a PVT block + * \author Carles Fernandez, 2018. cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "pvt_conf.h" + +Pvt_Conf::Pvt_Conf() +{ + type_of_receiver = 0U; + output_rate_ms = 0; + display_rate_ms = 0; + + rinex_version = 0; + rinexobs_rate_ms = 0; + rinexnav_rate_ms = 0; + + dump = false; + dump_mat = true; + + flag_nmea_tty_port = false; + + flag_rtcm_server = false; + flag_rtcm_tty_port = false; + rtcm_tcp_port = 0U; + rtcm_station_id = 0U; + + output_enabled = true; + rinex_output_enabled = true; + gpx_output_enabled = true; + geojson_output_enabled = true; + nmea_output_file_enabled = true; + kml_output_enabled = true; + xml_output_enabled = true; + rtcm_output_file_enabled = true; + + output_path = std::string("."); + rinex_output_path = std::string("."); + gpx_output_path = std::string("."); + geojson_output_path = std::string("."); + nmea_output_file_path = std::string("."); + kml_output_path = std::string("."); + xml_output_path = std::string("."); + rtcm_output_file_path = std::string("."); +} diff --git a/src/algorithms/PVT/libs/pvt_conf.h b/src/algorithms/PVT/libs/pvt_conf.h new file mode 100644 index 000000000..1719863e1 --- /dev/null +++ b/src/algorithms/PVT/libs/pvt_conf.h @@ -0,0 +1,86 @@ +/*! + * \file pvt_conf.h + * \brief Class that contains all the configuration parameters for the PVT block + * \author Carles Fernandez, 2018. cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_PVT_CONF_H_ +#define GNSS_SDR_PVT_CONF_H_ + +#include +#include +#include +#include + +class Pvt_Conf +{ +public: + uint32_t type_of_receiver; + int32_t output_rate_ms; + int32_t display_rate_ms; + + int32_t rinex_version; + int32_t rinexobs_rate_ms; + int32_t rinexnav_rate_ms; + std::map rtcm_msg_rate_ms; + + bool dump; + bool dump_mat; + std::string dump_filename; + + bool flag_nmea_tty_port; + std::string nmea_dump_filename; + std::string nmea_dump_devname; + + bool flag_rtcm_server; + bool flag_rtcm_tty_port; + uint16_t rtcm_tcp_port; + uint16_t rtcm_station_id; + std::string rtcm_dump_devname; + + bool output_enabled; + bool rinex_output_enabled; + bool gpx_output_enabled; + bool geojson_output_enabled; + bool nmea_output_file_enabled; + bool kml_output_enabled; + bool xml_output_enabled; + bool rtcm_output_file_enabled; + + std::string output_path; + std::string rinex_output_path; + std::string gpx_output_path; + std::string geojson_output_path; + std::string nmea_output_file_path; + std::string kml_output_path; + std::string xml_output_path; + std::string rtcm_output_file_path; + + Pvt_Conf(); +}; + +#endif diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index e09a4be8c..9a2ab524b 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -33,6 +33,9 @@ #include #include #include +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem #include #include // for getlogin_r() #include // for min and max @@ -48,14 +51,44 @@ using google::LogMessage; -Rinex_Printer::Rinex_Printer(int32_t conf_version) +Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path) { - navfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_GPS_NAV"); - obsfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_OBS"); - sbsfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_SBAS"); - navGalfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_GAL_NAV"); - navMixfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_MIXED_NAV"); - navGlofilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_GLO_NAV"); + std::string base_rinex_path = base_path; + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(base_rinex_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(base_rinex_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + base_rinex_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + base_rinex_path = p.string(); + } + if (base_rinex_path.compare(".") != 0) + { + std::cout << "RINEX files will be stored at " << base_rinex_path << std::endl; + } + + navfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_GPS_NAV"); + obsfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_OBS"); + sbsfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_SBAS"); + navGalfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_GAL_NAV"); + navMixfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_MIXED_NAV"); + navGlofilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_GLO_NAV"); Rinex_Printer::navFile.open(navfilename, std::ios::out | std::ios::in | std::ios::app); Rinex_Printer::obsFile.open(obsfilename, std::ios::out | std::ios::in | std::ios::app); @@ -64,6 +97,13 @@ Rinex_Printer::Rinex_Printer(int32_t conf_version) Rinex_Printer::navMixFile.open(navMixfilename, std::ios::out | std::ios::in | std::ios::app); Rinex_Printer::navGloFile.open(navGlofilename, std::ios::out | std::ios::in | std::ios::app); + if (!Rinex_Printer::navFile.is_open() or !Rinex_Printer::obsFile.is_open() or + !Rinex_Printer::sbsFile.is_open() or !Rinex_Printer::navGalFile.is_open() or + !Rinex_Printer::navMixFile.is_open() or !Rinex_Printer::navGloFile.is_open()) + { + std::cout << "RINEX files cannot be saved. Wrong permissions?" << std::endl; + } + // RINEX v3.02 codes satelliteSystem["GPS"] = "G"; satelliteSystem["GLONASS"] = "R"; @@ -477,6 +517,7 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Glonass_Gnav_Utc_M out << line << std::endl; } + void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) { if (glonass_gnav_almanac.i_satellite_freq_channel) @@ -725,13 +766,13 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps } -void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) { if (glonass_gnav_almanac.i_satellite_freq_channel) { } //Avoid compiler warning //Avoid compiler warning, there is not time system correction between Galileo and GLONASS - if (galileo_almanac.A_0G_10) + if (galileo_utc_model.A_0G_10) { } std::string line; @@ -839,7 +880,7 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& gali } -void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model) { std::string line; @@ -915,10 +956,10 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono // -------- Line system time correction 2 line.clear(); line += std::string("GPGA"); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_0G_10, 16, 2), 18); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_1G_10, 15, 2), 16); - line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.t_0G_10), 7); - line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.WN_0G_10), 5); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A_0G_10, 16, 2), 18); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A_1G_10, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.t_0G_10), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.WN_0G_10), 5); line += std::string(10, ' '); line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); Rinex_Printer::lengthCheck(line); @@ -1061,6 +1102,138 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& ion } +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& iono, const Gps_CNAV_Utc_Model& utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model) +{ + std::string line; + + // -------- Line 1 + line = std::string(5, ' '); + line += stringVersion; + line += std::string(11, ' '); + line += std::string("N: GNSS NAV DATA"); + line += std::string(4, ' '); + line += std::string("M: MIXED"); + line += std::string(12, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("GNSS NAVIGATION MESSAGE FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See https://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line ionospheric info 1 + line.clear(); + line += std::string("GAL "); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai0_5, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai1_5, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai2_5, 10, 2), 12); + double zero = 0.0; + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(zero, 10, 2), 12); + line += std::string(7, ' '); + line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line ionospheric info 2 + line.clear(); + line += std::string("GPSA"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha0, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha1, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha2, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha3, 10, 2), 12); + line += std::string(7, ' '); + line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line ionospheric info 3 + line.clear(); + line += std::string("GPSB"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta0, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta1, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta2, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta3, 10, 2), 12); + line += std::string(7, ' '); + line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction + line.clear(); + line += std::string("GAUT"); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A0_6, 16, 2), 18); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A1_6, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t0t_6), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WNot_6), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 2 + line.clear(); + line += std::string("GPUT"); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0, 16, 2), 18); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_t_OT), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_WN_T + 1024), 5); // valid until 2019 + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 6 leap seconds + // For leap second information, see http://www.endruntechnologies.com/leap.htm + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LS), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LSF), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_WN_LSF), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_DN), 6); + line += std::string(36, ' '); + line += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- End of Header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, const Gps_Utc_Model& utc_model) { std::string line; @@ -1238,7 +1411,7 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, co } -void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac) +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model) { std::string line; @@ -1327,10 +1500,10 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono // -------- Line system time correction 2 line.clear(); line += std::string("GPGA"); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_0G_10, 16, 2), 18); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_1G_10, 15, 2), 16); - line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.t_0G_10), 7); - line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.WN_0G_10), 5); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A_0G_10, 16, 2), 18); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A_1G_10, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t_0G_10), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WN_0G_10), 5); line += std::string(10, ' '); line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); Rinex_Printer::lengthCheck(line); @@ -1552,7 +1725,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Glonass_Gnav_Utc_ } -void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) +void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model) { std::vector data; std::string line_aux; @@ -1599,10 +1772,10 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& gal else if ((line_str.find("GPGA", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) { line_aux += std::string("GPGA"); - line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_0G_10, 16, 2), 18); - line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_1G_10, 15, 2), 16); - line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.t_0G_10), 7); - line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.WN_0G_10), 5); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A_0G_10, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A_1G_10, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.t_0G_10), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.WN_0G_10), 5); line_aux += std::string(10, ' '); line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); data.push_back(line_aux); @@ -1893,7 +2066,136 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Utc_Mode } -void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac) +void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Utc_Model& utc_model, const Gps_CNAV_Iono& iono, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model) +{ + std::vector data; + std::string line_aux; + + int64_t pos = out.tellp(); + out.seekp(0); + data.clear(); + + bool no_more_finds = false; + std::string line_str; + + while (!out.eof()) + { + std::getline(out, line_str); + + if (!no_more_finds) + { + line_aux.clear(); + if ((line_str.find("GAL", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos)) + { + line_aux += std::string("GAL "); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai0_5, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai1_5, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai2_5, 10, 2), 12); + double zero = 0.0; + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(zero, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPSA", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPSA"); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha3, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPSB", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPSB"); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta3, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + + else if ((line_str.find("GAUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GAUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A0_6, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A1_6, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t0t_6), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WNot_6), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPGA", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPGA"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A_0G_10, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A_1G_10, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t_0G_10), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WN_0G_10), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("GPUT", 0) != std::string::npos) + { + line_aux += std::string("GPUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_t_OT), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_WN_T + 1024), 5); // valid until 2019 + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("LEAP SECONDS", 59) != std::string::npos) + { + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LS), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_WN_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_DN), 6); + line_aux += std::string(36, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + } + else + { + data.push_back(line_str); + } + } + out.close(); + out.open(navfilename, std::ios::out | std::ios::trunc); + out.seekp(0); + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) + { + out << data[i] << std::endl; + } + out.close(); + out.open(navfilename, std::ios::out | std::ios::app); + out.seekp(pos); + std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl; +} + + +void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model) { std::vector data; std::string line_aux; @@ -1975,10 +2277,10 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_ion else if ((line_str.find("GPGA", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) { line_aux += std::string("GPGA"); - line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_0G_10, 16, 2), 18); - line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_1G_10, 15, 2), 16); - line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.t_0G_10), 7); - line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.WN_0G_10), 5); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A_0G_10, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A_1G_10, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t_0G_10), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WN_0G_10), 5); line_aux += std::string(10, ' '); line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); data.push_back(line_aux); @@ -2239,13 +2541,13 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Iono& gp } -void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) { if (glonass_gnav_almanac.i_satellite_freq_channel) { } //Avoid compiler warning //Avoid compiler warning, there is not time system correction between Galileo and GLONASS - if (galileo_almanac.A_0G_10) + if (galileo_utc_model.A_0G_10) { } std::vector data; @@ -3195,6 +3497,15 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_cnav_eph_map, const std::map& galileo_eph_map) +{ + version = 3; + stringVersion = "3.02"; + Rinex_Printer::log_rinex_nav(out, gps_cnav_eph_map); + Rinex_Printer::log_rinex_nav(out, galileo_eph_map); +} + + void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map) { Rinex_Printer::log_rinex_nav(out, gps_eph_map); @@ -4796,7 +5107,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph } -void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const double d_TOW_first_observation) +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const double d_TOW_first_observation, const std::string gps_bands) { std::string line; @@ -4934,30 +5245,66 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris // -------- SYS / OBS TYPES // one line per available system line.clear(); + uint32_t number_of_observations_gps = 0; + std::string signal_("2S"); + std::size_t found_2S = gps_bands.find(signal_); + if (found_2S != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + signal_ = "L5"; + std::size_t found_L5 = gps_bands.find(signal_); + if (found_L5 != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } line += satelliteSystem["GPS"]; line += std::string(2, ' '); std::stringstream strm; - numberTypesObservations = 4; + numberTypesObservations = number_of_observations_gps; strm << numberTypesObservations; line += Rinex_Printer::rightJustify(strm.str(), 3); // per type of observation - // GPS L2 PSEUDORANGE - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS L2 PHASE - line += std::string(1, ' '); - line += observationType["CARRIER_PHASE"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS DOPPLER L2 - line += std::string(1, ' '); - line += observationType["DOPPLER"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS L2 SIGNAL STRENGTH - line += std::string(1, ' '); - line += observationType["SIGNAL_STRENGTH"]; - line += observationCode["GPS_L2_L2CM"]; + if (found_2S != std::string::npos) + { + // GPS L2 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS DOPPLER L2 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L2_L2CM"]; + } + + if (found_L5 != std::string::npos) + { + // GPS L5 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L5_Q"]; + // GPS DOPPLER L5 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L5_Q"]; + } line += std::string(60 - line.size(), ' '); line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); Rinex_Printer::lengthCheck(line); @@ -5005,7 +5352,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris } -void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, const double d_TOW_first_observation) +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, const double d_TOW_first_observation, const std::string gps_bands) { if (eph_cnav.d_i_0) { @@ -5146,46 +5493,90 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph // -------- SYS / OBS TYPES // one line per available system line.clear(); + uint32_t number_of_observations_gps = 0; + std::string signal_("1C"); + std::size_t found_1C = gps_bands.find(signal_); + if (found_1C != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + signal_ = "2S"; + std::size_t found_2S = gps_bands.find(signal_); + if (found_2S != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + signal_ = "L5"; + std::size_t found_L5 = gps_bands.find(signal_); + if (found_L5 != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } line += satelliteSystem["GPS"]; line += std::string(2, ' '); std::stringstream strm; - numberTypesObservations = 8; + numberTypesObservations = number_of_observations_gps; strm << numberTypesObservations; line += Rinex_Printer::rightJustify(strm.str(), 3); // per type of observation - // GPS L1 PSEUDORANGE - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GPS_L1_CA"]; - // GPS L1 PHASE - line += std::string(1, ' '); - line += observationType["CARRIER_PHASE"]; - line += observationCode["GPS_L1_CA"]; - // GPS DOPPLER L1 - line += std::string(1, ' '); - line += observationType["DOPPLER"]; - line += observationCode["GPS_L1_CA"]; - // GPS L1 CA SIGNAL STRENGTH - line += std::string(1, ' '); - line += observationType["SIGNAL_STRENGTH"]; - line += observationCode["GPS_L1_CA"]; - // GPS L2 PSEUDORANGE - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS L2 PHASE - line += std::string(1, ' '); - line += observationType["CARRIER_PHASE"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS DOPPLER L2 - line += std::string(1, ' '); - line += observationType["DOPPLER"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS L2 SIGNAL STRENGTH - line += std::string(1, ' '); - line += observationType["SIGNAL_STRENGTH"]; - line += observationCode["GPS_L2_L2CM"]; + if (found_1C != std::string::npos) + { + // GPS L1 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L1_CA"]; + // GPS L1 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L1_CA"]; + // GPS DOPPLER L1 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L1_CA"]; + // GPS L1 CA SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L1_CA"]; + } + if (found_2S != std::string::npos) + { + // GPS L2 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS DOPPLER L2 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L2_L2CM"]; + } + if (found_L5 != std::string::npos) + { + // GPS L5 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L5_Q"]; + // GPS DOPPLER L5 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L5_Q"]; + } line += std::string(60 - line.size(), ' '); line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); Rinex_Printer::lengthCheck(line); @@ -5233,6 +5624,672 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph } +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& eph_cnav, const Galileo_Ephemeris& galileo_eph, const double d_TOW_first_observation, const std::string gps_bands, const std::string galileo_bands) +{ + std::string line; + version = 3; + if (eph_cnav.d_e_eccentricity == 0) + { + // avoid warning + } + if (galileo_eph.e_1 == 0) + { + // avoid warning + } + + // -------- Line 1 + line = std::string(5, ' '); + line += "3.02"; + line += std::string(11, ' '); + line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); + line += satelliteSystem["Mixed"]; + line += std::string(19, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::leftJustify("G = GPS R = GLONASS E = GALILEO S = GEO M = MIXED", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 3 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("MIXED (GPS/GALILEO) OBSERVATION DATA FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See https://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER NAME + line.clear(); + line += Rinex_Printer::leftJustify("DEFAULT MARKER NAME", 60); // put a flag or a property, + line += Rinex_Printer::leftJustify("MARKER NAME", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER TYPE + //line.clear(); + //line += Rinex_Printer::leftJustify("NON_GEODETIC", 20); // put a flag or a property + //line += std::string(40, ' '); + //line += Rinex_Printer::leftJustify("MARKER TYPE", 20); + //Rinex_Printer::lengthCheck(line); + //out << line << std::endl; + + // -------- Line OBSERVER / AGENCY + line.clear(); + std::string username; + char c_username[20] = {0}; + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); + if (nGet == 0) + { + username = c_username; + } + else + { + username = "UNKNOWN USER"; + } + line += leftJustify(username, 20); + line += Rinex_Printer::leftJustify("CTTC", 40); // add flag and property + line += Rinex_Printer::leftJustify("OBSERVER / AGENCY", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line REC / TYPE VERS + line.clear(); + line += Rinex_Printer::leftJustify("GNSS-SDR", 20); // add flag and property + line += Rinex_Printer::leftJustify("Software Receiver", 20); // add flag and property + //line += Rinex_Printer::leftJustify(google::VersionString(), 20); // add flag and property + if (gnss_sdr_version.length() > 20) gnss_sdr_version.resize(9, ' '); + line += Rinex_Printer::leftJustify(gnss_sdr_version, 20); + line += Rinex_Printer::leftJustify("REC # / TYPE / VERS", 20); + lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA TYPE + line.clear(); + line += Rinex_Printer::leftJustify("Antenna number", 20); // add flag and property + line += Rinex_Printer::leftJustify("Antenna type", 20); // add flag and property + line += std::string(20, ' '); + line += Rinex_Printer::leftJustify("ANT # / TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- APPROX POSITION (optional for moving platforms) + // put here real data! + double antena_x = 0.0; + double antena_y = 0.0; + double antena_z = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_x, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_y, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_z, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("APPROX POSITION XYZ", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA: DELTA H/E/N + // put here real data! + double antena_h = 0.0; + double antena_e = 0.0; + double antena_n = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_h, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_e, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_n, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("ANTENNA: DELTA H/E/N", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- SYS / OBS TYPES + // one line per available system + line.clear(); + uint32_t number_of_observations_gps = 0; + std::string signal_("1C"); + std::size_t found_1C = gps_bands.find(signal_); + if (found_1C != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + signal_ = "2S"; + std::size_t found_2S = gps_bands.find(signal_); + if (found_2S != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + signal_ = "L5"; + std::size_t found_L5 = gps_bands.find(signal_); + if (found_L5 != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + line += satelliteSystem["GPS"]; + line += std::string(2, ' '); + std::stringstream strm; + numberTypesObservations = number_of_observations_gps; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 3); + // per type of observation + if (found_1C != std::string::npos) + { + // GPS L1 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L1_CA"]; + // GPS L1 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L1_CA"]; + // GPS DOPPLER L1 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L1_CA"]; + // GPS L1 CA SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L1_CA"]; + } + if (found_2S != std::string::npos) + { + // GPS L2 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS DOPPLER L2 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L2_L2CM"]; + } + if (found_L5 != std::string::npos) + { + // GPS L5 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L5_Q"]; + // GPS DOPPLER L5 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L5_Q"]; + } + line += std::string(60 - line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + line.clear(); + uint32_t number_of_observations_gal = 0; + signal_ = "1B"; + std::size_t found_1B = galileo_bands.find(signal_); + if (found_1B != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + signal_ = "5X"; + std::size_t found_5X = galileo_bands.find(signal_); + if (found_5X != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + signal_ = "7X"; + std::size_t found_7X = galileo_bands.find(signal_); + if (found_7X != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + line += satelliteSystem["Galileo"]; + line += std::string(2, ' '); + line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_gal), 3); + if (found_1B != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E1_B"]; + } + if (found_5X != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E5a_IQ"]; + } + if (found_7X != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E5b_IQ"]; + } + line += std::string(60 - line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Signal Strength units + line.clear(); + line += Rinex_Printer::leftJustify("DBHZ", 20); + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- TIME OF FIRST OBS + line.clear(); + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(gps_eph, d_TOW_first_observation); + std::string timestring = boost::posix_time::to_iso_string(p_gps_time); + std::string year(timestring, 0, 4); + std::string month(timestring, 4, 2); + std::string day(timestring, 6, 2); + std::string hour(timestring, 9, 2); + std::string minutes(timestring, 11, 2); + double gps_t = d_TOW_first_observation; + double seconds = fmod(gps_t, 60); + line += Rinex_Printer::rightJustify(year, 6); + line += Rinex_Printer::rightJustify(month, 6); + line += Rinex_Printer::rightJustify(day, 6); + line += Rinex_Printer::rightJustify(hour, 6); + line += Rinex_Printer::rightJustify(minutes, 6); + line += Rinex_Printer::rightJustify(asString(seconds, 7), 13); + line += Rinex_Printer::rightJustify(std::string("GPS"), 8); + line += std::string(9, ' '); + line += Rinex_Printer::leftJustify("TIME OF FIRST OBS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- end of header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& eph_cnav, const Galileo_Ephemeris& galileo_eph, const double d_TOW_first_observation, const std::string gps_bands, const std::string galileo_bands) +{ + std::string line; + version = 3; + if (galileo_eph.e_1 == 0) + { + // avoid warning + } + // -------- Line 1 + line = std::string(5, ' '); + line += "3.02"; + line += std::string(11, ' '); + line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); + line += satelliteSystem["Mixed"]; + line += std::string(19, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::leftJustify("G = GPS R = GLONASS E = GALILEO S = GEO M = MIXED", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 3 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("MIXED (GPS/GALILEO) OBSERVATION DATA FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See https://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER NAME + line.clear(); + line += Rinex_Printer::leftJustify("DEFAULT MARKER NAME", 60); // put a flag or a property, + line += Rinex_Printer::leftJustify("MARKER NAME", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER TYPE + //line.clear(); + //line += Rinex_Printer::leftJustify("NON_GEODETIC", 20); // put a flag or a property + //line += std::string(40, ' '); + //line += Rinex_Printer::leftJustify("MARKER TYPE", 20); + //Rinex_Printer::lengthCheck(line); + //out << line << std::endl; + + // -------- Line OBSERVER / AGENCY + line.clear(); + std::string username; + char c_username[20] = {0}; + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); + if (nGet == 0) + { + username = c_username; + } + else + { + username = "UNKNOWN USER"; + } + line += leftJustify(username, 20); + line += Rinex_Printer::leftJustify("CTTC", 40); // add flag and property + line += Rinex_Printer::leftJustify("OBSERVER / AGENCY", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line REC / TYPE VERS + line.clear(); + line += Rinex_Printer::leftJustify("GNSS-SDR", 20); // add flag and property + line += Rinex_Printer::leftJustify("Software Receiver", 20); // add flag and property + //line += Rinex_Printer::leftJustify(google::VersionString(), 20); // add flag and property + if (gnss_sdr_version.length() > 20) gnss_sdr_version.resize(9, ' '); + line += Rinex_Printer::leftJustify(gnss_sdr_version, 20); + line += Rinex_Printer::leftJustify("REC # / TYPE / VERS", 20); + lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA TYPE + line.clear(); + line += Rinex_Printer::leftJustify("Antenna number", 20); // add flag and property + line += Rinex_Printer::leftJustify("Antenna type", 20); // add flag and property + line += std::string(20, ' '); + line += Rinex_Printer::leftJustify("ANT # / TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- APPROX POSITION (optional for moving platforms) + // put here real data! + double antena_x = 0.0; + double antena_y = 0.0; + double antena_z = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_x, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_y, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_z, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("APPROX POSITION XYZ", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA: DELTA H/E/N + // put here real data! + double antena_h = 0.0; + double antena_e = 0.0; + double antena_n = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_h, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_e, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_n, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("ANTENNA: DELTA H/E/N", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- SYS / OBS TYPES + // one line per available system + line.clear(); + uint32_t number_of_observations_gps = 0; + std::string signal_("2S"); + std::size_t found_2S = gps_bands.find(signal_); + if (found_2S != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + signal_ = "L5"; + std::size_t found_L5 = gps_bands.find(signal_); + if (found_L5 != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + line += satelliteSystem["GPS"]; + line += std::string(2, ' '); + std::stringstream strm; + numberTypesObservations = number_of_observations_gps; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 3); + // per type of observation + if (found_2S != std::string::npos) + { + // GPS L2 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS DOPPLER L2 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L2_L2CM"]; + } + if (found_L5 != std::string::npos) + { + // GPS L5 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L5_Q"]; + // GPS DOPPLER L5 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L5_Q"]; + } + line += std::string(60 - line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + line.clear(); + uint32_t number_of_observations_gal = 0; + signal_ = "1B"; + std::size_t found_1B = galileo_bands.find(signal_); + if (found_1B != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + signal_ = "5X"; + std::size_t found_5X = galileo_bands.find(signal_); + if (found_5X != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + signal_ = "7X"; + std::size_t found_7X = galileo_bands.find(signal_); + if (found_7X != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + line += satelliteSystem["Galileo"]; + line += std::string(2, ' '); + line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_gal), 3); + if (found_1B != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E1_B"]; + } + if (found_5X != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E5a_IQ"]; + } + if (found_7X != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E5b_IQ"]; + } + line += std::string(60 - line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Signal Strength units + line.clear(); + line += Rinex_Printer::leftJustify("DBHZ", 20); + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- TIME OF FIRST OBS + line.clear(); + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(eph_cnav, d_TOW_first_observation); + std::string timestring = boost::posix_time::to_iso_string(p_gps_time); + std::string year(timestring, 0, 4); + std::string month(timestring, 4, 2); + std::string day(timestring, 6, 2); + std::string hour(timestring, 9, 2); + std::string minutes(timestring, 11, 2); + double gps_t = d_TOW_first_observation; + double seconds = fmod(gps_t, 60); + line += Rinex_Printer::rightJustify(year, 6); + line += Rinex_Printer::rightJustify(month, 6); + line += Rinex_Printer::rightJustify(day, 6); + line += Rinex_Printer::rightJustify(hour, 6); + line += Rinex_Printer::rightJustify(minutes, 6); + line += Rinex_Printer::rightJustify(asString(seconds, 7), 13); + line += Rinex_Printer::rightJustify(std::string("GPS"), 8); + line += std::string(9, ' '); + line += Rinex_Printer::leftJustify("TIME OF FIRST OBS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- end of header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& eph, const double d_TOW_first_observation, const std::string bands) { std::string line; @@ -7442,6 +8499,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c //Get maps with GPS L1 and L2 observations std::map observablesL1; std::map observablesL2; + std::map observablesL5; std::map::const_iterator observables_iter; std::multimap total_mmap; @@ -7468,6 +8526,18 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c } total_mmap.insert(std::pair(observables_iter->second.PRN, observables_iter->second)); } + + if ((system_.compare("G") == 0) && (sig_.compare("L5") == 0)) + { + observablesL5.insert(std::pair(observables_iter->first, observables_iter->second)); + mmap_iter = total_mmap.find(observables_iter->second.PRN); + if (mmap_iter == total_mmap.end()) + { + Gnss_Synchro gs = Gnss_Synchro(); + total_mmap.insert(std::pair(observables_iter->second.PRN, gs)); + } + total_mmap.insert(std::pair(observables_iter->second.PRN, observables_iter->second)); + } } // Fill with zeros satellites with L1 obs but not L2 @@ -7515,6 +8585,18 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c } } + for (observables_iter = observablesL5.cbegin(); + observables_iter != observablesL5.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + it = available_prns.find(prn_); + if (it == available_prns.end()) + { + available_prns.insert(prn_); + } + } + int32_t numSatellitesObserved = available_prns.size(); line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); // Receiver clock offset (optional) @@ -8081,6 +9163,603 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const Galileo_Ephemeris& galileo_eph, double gps_obs_time, const std::map& observables) +{ + if (galileo_eph.e_1) + { + } // avoid warning, not needed + std::string line; + + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(eph, gps_obs_time); + std::string timestring = boost::posix_time::to_iso_string(p_gps_time); + //double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time)); + //double gps_t = eph.sv_clock_correction(obs_time); + double gps_t = gps_obs_time; + + std::string month(timestring, 4, 2); + std::string day(timestring, 6, 2); + std::string hour(timestring, 9, 2); + std::string minutes(timestring, 11, 2); + + std::string year(timestring, 0, 4); + line += std::string(1, '>'); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + + line += std::string(1, ' '); + double seconds = fmod(gps_t, 60); + // Add extra 0 if seconds are < 10 + if (seconds < 10) + { + line += std::string(1, '0'); + } + line += Rinex_Printer::asString(seconds, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + + //Number of satellites observed in current epoch + + //Get maps with observations + std::map observablesG2S; + std::map observablesGL5; + std::map observablesE1B; + std::map observablesE5A; + std::map observablesE5B; + std::map::const_iterator observables_iter; + + for (observables_iter = observables.cbegin(); + observables_iter != observables.cend(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if ((system_.compare("E") == 0) && (sig_.compare("1B") == 0)) + { + observablesE1B.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("E") == 0) && (sig_.compare("5X") == 0)) + { + observablesE5A.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("E") == 0) && (sig_.compare("7X") == 0)) + { + observablesE5B.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("G") == 0) && (sig_.compare("2S") == 0)) + { + observablesG2S.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("G") == 0) && (sig_.compare("L5") == 0)) + { + observablesGL5.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + + std::multimap total_gps_map; + std::multimap total_gal_map; + std::set available_gal_prns; + std::set available_gps_prns; + std::set::iterator it; + for (observables_iter = observablesE1B.cbegin(); + observables_iter != observablesE1B.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gal_prns.find(prn_); + if (it == available_gal_prns.end()) + { + available_gal_prns.insert(prn_); + } + } + + for (observables_iter = observablesE5A.cbegin(); + observables_iter != observablesE5A.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gal_prns.find(prn_); + if (it == available_gal_prns.end()) + { + available_gal_prns.insert(prn_); + } + } + + for (observables_iter = observablesE5B.cbegin(); + observables_iter != observablesE5B.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gal_prns.find(prn_); + if (it == available_gal_prns.end()) + { + available_gal_prns.insert(prn_); + } + } + + for (observables_iter = observablesG2S.cbegin(); + observables_iter != observablesG2S.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gps_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gps_prns.find(prn_); + if (it == available_gps_prns.end()) + { + available_gps_prns.insert(prn_); + } + } + + for (observables_iter = observablesGL5.cbegin(); + observables_iter != observablesGL5.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gps_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gps_prns.find(prn_); + if (it == available_gps_prns.end()) + { + available_gps_prns.insert(prn_); + } + } + + int32_t numGalSatellitesObserved = available_gal_prns.size(); + int32_t numGpsSatellitesObserved = available_gps_prns.size(); + int32_t numSatellitesObserved = numGalSatellitesObserved + numGpsSatellitesObserved; + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + + // Receiver clock offset (optional) + //line += rightJustify(asString(clockOffset, 12), 15); + + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + std::string s; + std::string lineObs; + + std::pair::iterator, std::multimap::iterator> ret; + for (it = available_gps_prns.begin(); + it != available_gps_prns.end(); + it++) + { + lineObs.clear(); + lineObs += satelliteSystem["GPS"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + ret = total_gps_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int32_t lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GALILEO_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + out << lineObs << std::endl; + } + + for (it = available_gal_prns.begin(); + it != available_gal_prns.end(); + it++) + { + lineObs.clear(); + lineObs += satelliteSystem["Galileo"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + ret = total_gal_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int32_t lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // Galileo CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GALILEO_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // Galileo DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // Galileo SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + //if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } +} + + +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& gps_cnav_eph, const Galileo_Ephemeris& galileo_eph, double gps_obs_time, const std::map& observables) +{ + if (galileo_eph.e_1) + { + } // avoid warning, not needed + if (gps_cnav_eph.d_e_eccentricity) + { + } // avoid warning, not needed + std::string line; + + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(gps_eph, gps_obs_time); + std::string timestring = boost::posix_time::to_iso_string(p_gps_time); + //double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time)); + //double gps_t = eph.sv_clock_correction(obs_time); + double gps_t = gps_obs_time; + + std::string month(timestring, 4, 2); + std::string day(timestring, 6, 2); + std::string hour(timestring, 9, 2); + std::string minutes(timestring, 11, 2); + + std::string year(timestring, 0, 4); + line += std::string(1, '>'); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + + line += std::string(1, ' '); + double seconds = fmod(gps_t, 60); + // Add extra 0 if seconds are < 10 + if (seconds < 10) + { + line += std::string(1, '0'); + } + line += Rinex_Printer::asString(seconds, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + + //Number of satellites observed in current epoch + + //Get maps with observations + std::map observablesG2S; + std::map observablesGL5; + std::map observablesG1C; + std::map observablesE1B; + std::map observablesE5A; + std::map observablesE5B; + std::map::const_iterator observables_iter; + + for (observables_iter = observables.cbegin(); + observables_iter != observables.cend(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if ((system_.compare("E") == 0) && (sig_.compare("1B") == 0)) + { + observablesE1B.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("E") == 0) && (sig_.compare("5X") == 0)) + { + observablesE5A.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("E") == 0) && (sig_.compare("7X") == 0)) + { + observablesE5B.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("G") == 0) && (sig_.compare("2S") == 0)) + { + observablesG2S.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("G") == 0) && (sig_.compare("L5") == 0)) + { + observablesGL5.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) + { + observablesG1C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + + std::multimap total_gps_map; + std::multimap total_gal_map; + std::set available_gal_prns; + std::set available_gps_prns; + std::set::iterator it; + for (observables_iter = observablesE1B.cbegin(); + observables_iter != observablesE1B.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gal_prns.find(prn_); + if (it == available_gal_prns.end()) + { + available_gal_prns.insert(prn_); + } + } + + for (observables_iter = observablesE5A.cbegin(); + observables_iter != observablesE5A.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gal_prns.find(prn_); + if (it == available_gal_prns.end()) + { + available_gal_prns.insert(prn_); + } + } + + for (observables_iter = observablesE5B.cbegin(); + observables_iter != observablesE5B.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gal_prns.find(prn_); + if (it == available_gal_prns.end()) + { + available_gal_prns.insert(prn_); + } + } + + for (observables_iter = observablesG1C.cbegin(); + observables_iter != observablesG1C.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gps_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gps_prns.find(prn_); + if (it == available_gps_prns.end()) + { + available_gps_prns.insert(prn_); + } + } + + for (observables_iter = observablesG2S.cbegin(); + observables_iter != observablesG2S.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gps_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gps_prns.find(prn_); + if (it == available_gps_prns.end()) + { + available_gps_prns.insert(prn_); + } + } + + for (observables_iter = observablesGL5.cbegin(); + observables_iter != observablesGL5.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gps_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gps_prns.find(prn_); + if (it == available_gps_prns.end()) + { + available_gps_prns.insert(prn_); + } + } + + int32_t numGalSatellitesObserved = available_gal_prns.size(); + int32_t numGpsSatellitesObserved = available_gps_prns.size(); + int32_t numSatellitesObserved = numGalSatellitesObserved + numGpsSatellitesObserved; + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + + // Receiver clock offset (optional) + //line += rightJustify(asString(clockOffset, 12), 15); + + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + std::string s; + std::string lineObs; + + std::pair::iterator, std::multimap::iterator> ret; + for (it = available_gps_prns.begin(); + it != available_gps_prns.end(); + it++) + { + lineObs.clear(); + lineObs += satelliteSystem["GPS"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + ret = total_gps_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int32_t lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GALILEO_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + out << lineObs << std::endl; + } + + for (it = available_gal_prns.begin(); + it != available_gal_prns.end(); + it++) + { + lineObs.clear(); + lineObs += satelliteSystem["Galileo"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + ret = total_gal_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int32_t lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // Galileo CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GALILEO_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // Galileo DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // Galileo SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + //if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } +} + + void Rinex_Printer::to_date_time(int32_t gps_week, int32_t gps_tow, int& year, int& month, int& day, int& hour, int& minute, int& second) { // represents GPS time (week, TOW) in the date time format of the Gregorian calendar. diff --git a/src/algorithms/PVT/libs/rinex_printer.h b/src/algorithms/PVT/libs/rinex_printer.h index faa3599d1..dde6724a6 100644 --- a/src/algorithms/PVT/libs/rinex_printer.h +++ b/src/algorithms/PVT/libs/rinex_printer.h @@ -77,12 +77,12 @@ class Rinex_Printer { public: /*! - * \brief Default constructor. Creates GPS Navigation and Observables RINEX files and their headers + * \brief Default constructor. Creates GNSS Navigation and Observables RINEX files and their headers */ - Rinex_Printer(int version = 0); + Rinex_Printer(int version = 0, const std::string& base_path = "."); /*! - * \brief Default destructor. Closes GPS Navigation and Observables RINEX files + * \brief Default destructor. Closes GNSS Navigation and Observables RINEX files */ ~Rinex_Printer(); @@ -106,12 +106,17 @@ public: /*! * \brief Generates the Galileo Navigation Data header */ - void rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac); + void rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model); /*! * \brief Generates the Mixed (GPS/Galileo) Navigation Data header */ - void rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac); + void rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model); + + /*! + * \brief Generates the Mixed (GPS CNAV/Galileo) Navigation Data header + */ + void rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& iono, const Gps_CNAV_Utc_Model& utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model); /*! * \brief Generates the GLONASS L1, L2 C/A Navigation Data header @@ -121,7 +126,7 @@ public: /*! * \brief Generates the Mixed (Galileo/GLONASS) Navigation Data header */ - void rinex_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); + void rinex_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); /*! * \brief Generates the Mixed (GPS L1 C/A/GLONASS L1, L2) Navigation Data header @@ -129,8 +134,8 @@ public: void rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); /*! - * \brief Generates the Mixed (GPS L2C C/A/GLONASS L1, L2) Navigation Data header - */ + * \brief Generates the Mixed (GPS L2C C/A/GLONASS L1, L2) Navigation Data header + */ void rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps_iono, const Gps_CNAV_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); /*! @@ -141,12 +146,12 @@ public: /*! * \brief Generates the GPS L2 Observation data header */ - void rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const double d_TOW_first_observation); + void rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const double d_TOW_first_observation, const std::string gps_bands = "2S"); /*! - * \brief Generates the dual frequency GPS L1 & L2 Observation data header + * \brief Generates the dual frequency GPS L1 & L2/L5 Observation data header */ - void rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, const double d_TOW_first_observation); + void rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, const double d_TOW_first_observation, const std::string gps_bands = "1C 2S"); /*! * \brief Generates the Galileo Observation data header. Example: bands("1B"), bands("1B 5X"), bands("5X"), ... Default: "1B". @@ -158,6 +163,16 @@ public: */ void rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, const double d_TOW_first_observation, const std::string galileo_bands = "1B"); + /*! + * \brief Generates the Mixed (GPS/Galileo) Observation data header. Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B". + */ + void rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& eph_cnav, const Galileo_Ephemeris& galileo_eph, const double d_TOW_first_observation, const std::string gps_bands = "1C 2S", const std::string galileo_bands = "1B"); + + /*! + * \brief Generates the Mixed (GPS/Galileo) Observation data header. Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B". + */ + void rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& eph_cnav, const Galileo_Ephemeris& galileo_eph, const double d_TOW_first_observation, const std::string gps_bands = "2S", const std::string galileo_bands = "1B"); + /*! * \brief Generates the GLONASS GNAV Observation data header. Example: bands("1C"), bands("1C 2C"), bands("2C"), ... Default: "1C". */ @@ -239,6 +254,11 @@ public: */ void log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map); + /*! + * \brief Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file + */ + void log_rinex_nav(std::fstream& out, const std::map& gps_cnav_eph_map, const std::map& galileo_eph_map); + /*! * \brief Writes data from the GLONASS GNAV navigation message into the RINEX file */ @@ -284,6 +304,16 @@ public: */ void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, const double gps_obs_time, const std::map& observables); + /*! + * \brief Writes Mixed GPS / Galileo observables into the RINEX file + */ + void log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const Galileo_Ephemeris& galileo_eph, double gps_obs_time, const std::map& observables); + + /*! + * \brief Writes Mixed GPS / Galileo observables into the RINEX file + */ + void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& gps_cnav_eph, const Galileo_Ephemeris& galileo_eph, double gps_obs_time, const std::map& observables); + /*! * \brief Writes GLONASS GNAV observables into the RINEX file. Example: glonass_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B". */ @@ -318,9 +348,11 @@ public: void update_nav_header(std::fstream& out, const Gps_CNAV_Utc_Model& utc_model, const Gps_CNAV_Iono& iono); - void update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac); + void update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model); - void update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac); + void update_nav_header(std::fstream& out, const Gps_CNAV_Utc_Model& utc_model, const Gps_CNAV_Iono& iono, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model); + + void update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model); void update_nav_header(std::fstream& out, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); @@ -328,7 +360,7 @@ public: void update_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps_cnav_iono, const Gps_CNAV_Utc_Model& gps_cnav_utc, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); - void update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); + void update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); void update_obs_header(std::fstream& out, const Gps_Utc_Model& utc_model); diff --git a/src/algorithms/PVT/libs/rtcm_printer.cc b/src/algorithms/PVT/libs/rtcm_printer.cc index 1603ca09d..400132e0c 100644 --- a/src/algorithms/PVT/libs/rtcm_printer.cc +++ b/src/algorithms/PVT/libs/rtcm_printer.cc @@ -33,6 +33,9 @@ #include "rtcm_printer.h" #include +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem #include #include #include // for O_RDWR @@ -42,10 +45,45 @@ using google::LogMessage; -Rtcm_Printer::Rtcm_Printer(std::string filename, bool flag_rtcm_server, bool flag_rtcm_tty_port, uint16_t rtcm_tcp_port, uint16_t rtcm_station_id, std::string rtcm_dump_devname, bool time_tag_name) +Rtcm_Printer::Rtcm_Printer(std::string filename, bool flag_rtcm_file_dump, bool flag_rtcm_server, bool flag_rtcm_tty_port, uint16_t rtcm_tcp_port, uint16_t rtcm_station_id, std::string rtcm_dump_devname, bool time_tag_name, const std::string& base_path) { boost::posix_time::ptime pt = boost::posix_time::second_clock::local_time(); tm timeinfo = boost::posix_time::to_tm(pt); + d_rtcm_file_dump = flag_rtcm_file_dump; + rtcm_base_path = base_path; + if (d_rtcm_file_dump) + { + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(rtcm_base_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(rtcm_base_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + rtcm_base_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + rtcm_base_path = p.string(); + } + if (rtcm_base_path.compare(".") != 0) + { + std::cout << "RTCM binary file will be stored at " << rtcm_base_path << std::endl; + } + + rtcm_base_path = rtcm_base_path + boost::filesystem::path::preferred_separator; + } if (time_tag_name) { @@ -89,11 +127,18 @@ Rtcm_Printer::Rtcm_Printer(std::string filename, bool flag_rtcm_server, bool fla { rtcm_filename = filename + ".rtcm"; } - - rtcm_file_descriptor.open(rtcm_filename.c_str(), std::ios::out); - if (rtcm_file_descriptor.is_open()) + rtcm_filename = rtcm_base_path + rtcm_filename; + if (d_rtcm_file_dump) { - DLOG(INFO) << "RTCM printer writing on " << rtcm_filename.c_str(); + rtcm_file_descriptor.open(rtcm_filename.c_str(), std::ios::out); + if (rtcm_file_descriptor.is_open()) + { + DLOG(INFO) << "RTCM printer writing on " << rtcm_filename.c_str(); + } + else + { + std::cout << "File " << rtcm_filename << "cannot be saved. Wrong permissions?" << std::endl; + } } rtcm_devname = rtcm_dump_devname; @@ -341,14 +386,17 @@ void Rtcm_Printer::close_serial() bool Rtcm_Printer::Print_Message(const std::string& message) { //write to file - try + if (d_rtcm_file_dump) { - rtcm_file_descriptor << message << std::endl; - } - catch (const std::exception& ex) - { - DLOG(INFO) << "RTCM printer cannot write on the output file " << rtcm_filename.c_str(); - return false; + try + { + rtcm_file_descriptor << message << std::endl; + } + catch (const std::exception& ex) + { + DLOG(INFO) << "RTCM printer cannot write on the output file " << rtcm_filename.c_str(); + return false; + } } //write to serial device diff --git a/src/algorithms/PVT/libs/rtcm_printer.h b/src/algorithms/PVT/libs/rtcm_printer.h index 87a710812..bb34f7ea6 100644 --- a/src/algorithms/PVT/libs/rtcm_printer.h +++ b/src/algorithms/PVT/libs/rtcm_printer.h @@ -48,7 +48,7 @@ public: /*! * \brief Default constructor. */ - Rtcm_Printer(std::string filename, bool flag_rtcm_server, bool flag_rtcm_tty_port, uint16_t rtcm_tcp_port, uint16_t rtcm_station_id, std::string rtcm_dump_filename, bool time_tag_name = true); + Rtcm_Printer(std::string filename, bool flag_rtcm_file_dump, bool flag_rtcm_server, bool flag_rtcm_tty_port, uint16_t rtcm_tcp_port, uint16_t rtcm_station_id, std::string rtcm_dump_filename, bool time_tag_name = true, const std::string& base_path = "."); /*! * \brief Default destructor. @@ -142,7 +142,8 @@ public: uint32_t lock_time(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro); private: - std::string rtcm_filename; // String with the RTCM log filename + std::string rtcm_filename; // String with the RTCM log filename + std::string rtcm_base_path; std::ofstream rtcm_file_descriptor; // Output file stream for RTCM log file std::string rtcm_devname; uint16_t port; @@ -152,6 +153,7 @@ private: void close_serial(); std::shared_ptr rtcm; bool Print_Message(const std::string& message); + bool d_rtcm_file_dump; }; #endif diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index 4d43c18b4..12d316196 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -56,17 +56,19 @@ #include "GPS_L1_CA.h" #include "Galileo_E1.h" #include "GLONASS_L1_L2_CA.h" +#include #include using google::LogMessage; -rtklib_solver::rtklib_solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, rtk_t& rtk) +rtklib_solver::rtklib_solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, bool flag_dump_to_mat, rtk_t &rtk) { // init empty ephemeris for all the available GNSS channels d_nchannels = nchannels; d_dump_filename = dump_filename; d_flag_dump_enabled = flag_dump_to_file; + d_flag_dump_mat_enabled = flag_dump_to_mat; count_valid_position = 0; this->set_averaging_flag(false); rtk_ = rtk; @@ -84,7 +86,7 @@ rtklib_solver::rtklib_solver(int nchannels, std::string dump_filename, bool flag d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); LOG(INFO) << "PVT lib dump enabled Log file: " << d_dump_filename.c_str(); } - catch (const std::ifstream::failure& e) + catch (const std::ifstream::failure &e) { LOG(WARNING) << "Exception opening RTKLIB dump file " << e.what(); } @@ -92,6 +94,301 @@ rtklib_solver::rtklib_solver(int nchannels, std::string dump_filename, bool flag } } +bool rtklib_solver::save_matfile() +{ + // READ DUMP FILE + std::string dump_filename = d_dump_filename; + std::ifstream::pos_type size; + int32_t number_of_double_vars = 21; + int32_t number_of_uint32_vars = 2; + int32_t number_of_uint8_vars = 3; + int32_t number_of_float_vars = 2; + int32_t epoch_size_bytes = sizeof(double) * number_of_double_vars + + sizeof(uint32_t) * number_of_uint32_vars + + sizeof(uint8_t) * number_of_uint8_vars + + sizeof(float) * number_of_float_vars; + std::ifstream dump_file; + std::cout << "Generating .mat file for " << dump_filename << std::endl; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return false; + } + // count number of epochs and rewind + int64_t num_epoch = 0LL; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return false; + } + + uint32_t *TOW_at_current_symbol_ms = new uint32_t[num_epoch]; + uint32_t *week = new uint32_t[num_epoch]; + double *RX_time = new double[num_epoch]; + double *user_clk_offset = new double[num_epoch]; + double *pos_x = new double[num_epoch]; + double *pos_y = new double[num_epoch]; + double *pos_z = new double[num_epoch]; + double *vel_x = new double[num_epoch]; + double *vel_y = new double[num_epoch]; + double *vel_z = new double[num_epoch]; + double *cov_xx = new double[num_epoch]; + double *cov_yy = new double[num_epoch]; + double *cov_zz = new double[num_epoch]; + double *cov_xy = new double[num_epoch]; + double *cov_yz = new double[num_epoch]; + double *cov_zx = new double[num_epoch]; + double *latitude = new double[num_epoch]; + double *longitude = new double[num_epoch]; + double *height = new double[num_epoch]; + uint8_t *valid_sats = new uint8_t[num_epoch]; + uint8_t *solution_status = new uint8_t[num_epoch]; + uint8_t *solution_type = new uint8_t[num_epoch]; + float *AR_ratio_factor = new float[num_epoch]; + float *AR_ratio_threshold = new float[num_epoch]; + double *gdop = new double[num_epoch]; + double *pdop = new double[num_epoch]; + double *hdop = new double[num_epoch]; + double *vdop = new double[num_epoch]; + + try + { + if (dump_file.is_open()) + { + for (int64_t i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_ms[i]), sizeof(uint32_t)); + dump_file.read(reinterpret_cast(&week[i]), sizeof(uint32_t)); + dump_file.read(reinterpret_cast(&RX_time[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&user_clk_offset[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&pos_x[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&pos_y[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&pos_z[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&vel_x[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&vel_y[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&vel_z[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&cov_xx[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&cov_yy[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&cov_zz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&cov_xy[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&cov_yz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&cov_zx[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&latitude[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&longitude[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&height[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&valid_sats[i]), sizeof(uint8_t)); + dump_file.read(reinterpret_cast(&solution_status[i]), sizeof(uint8_t)); + dump_file.read(reinterpret_cast(&solution_type[i]), sizeof(uint8_t)); + dump_file.read(reinterpret_cast(&AR_ratio_factor[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&AR_ratio_threshold[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&gdop[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&pdop[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&hdop[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&vdop[i]), sizeof(double)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] TOW_at_current_symbol_ms; + delete[] week; + delete[] RX_time; + delete[] user_clk_offset; + delete[] pos_x; + delete[] pos_y; + delete[] pos_z; + delete[] vel_x; + delete[] vel_y; + delete[] vel_z; + delete[] cov_xx; + delete[] cov_yy; + delete[] cov_zz; + delete[] cov_xy; + delete[] cov_yz; + delete[] cov_zx; + delete[] latitude; + delete[] longitude; + delete[] height; + delete[] valid_sats; + delete[] solution_status; + delete[] solution_type; + delete[] AR_ratio_factor; + delete[] AR_ratio_threshold; + delete[] gdop; + delete[] pdop; + delete[] hdop; + delete[] vdop; + + return false; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if (reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("TOW_at_current_symbol_ms", MAT_C_UINT32, MAT_T_UINT32, 2, dims, TOW_at_current_symbol_ms, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("week", MAT_C_UINT32, MAT_T_UINT32, 2, dims, week, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("RX_time", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, RX_time, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("user_clk_offset", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, user_clk_offset, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("pos_x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pos_x, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("pos_y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pos_y, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("pos_z", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pos_z, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("vel_x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vel_x, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("vel_y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vel_y, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("vel_z", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vel_z, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("cov_xx", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_xx, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("cov_yy", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_yy, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("cov_zz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_zz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("cov_xy", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_xy, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("cov_yz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_yz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("cov_zx", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_zx, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("latitude", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, latitude, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("longitude", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, longitude, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("height", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, height, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("valid_sats", MAT_C_UINT8, MAT_T_UINT8, 2, dims, valid_sats, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("solution_status", MAT_C_UINT8, MAT_T_UINT8, 2, dims, solution_status, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("solution_type", MAT_C_UINT8, MAT_T_UINT8, 2, dims, solution_type, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("AR_ratio_factor", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, AR_ratio_factor, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("AR_ratio_threshold", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, AR_ratio_threshold, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("gdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, gdop, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("pdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pdop, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("hdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, hdop, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("vdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vdop, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + + Mat_Close(matfp); + delete[] TOW_at_current_symbol_ms; + delete[] week; + delete[] RX_time; + delete[] user_clk_offset; + delete[] pos_x; + delete[] pos_y; + delete[] pos_z; + delete[] vel_x; + delete[] vel_y; + delete[] vel_z; + delete[] cov_xx; + delete[] cov_yy; + delete[] cov_zz; + delete[] cov_xy; + delete[] cov_yz; + delete[] cov_zx; + delete[] latitude; + delete[] longitude; + delete[] height; + delete[] valid_sats; + delete[] solution_status; + delete[] solution_type; + delete[] AR_ratio_factor; + delete[] AR_ratio_threshold; + delete[] gdop; + delete[] pdop; + delete[] hdop; + delete[] vdop; + + return true; +} rtklib_solver::~rtklib_solver() { @@ -101,11 +398,15 @@ rtklib_solver::~rtklib_solver() { d_dump_file.close(); } - catch (const std::exception& ex) + catch (const std::exception &ex) { LOG(WARNING) << "Exception in destructor closing the RTKLIB dump file " << ex.what(); } } + if (d_flag_dump_mat_enabled) + { + save_matfile(); + } } @@ -133,7 +434,7 @@ double rtklib_solver::get_vdop() const } -bool rtklib_solver::get_PVT(const std::map& gnss_observables_map, bool flag_averaging) +bool rtklib_solver::get_PVT(const std::map &gnss_observables_map, bool flag_averaging) { std::map::const_iterator gnss_observables_iter; std::map::const_iterator galileo_ephemeris_iter; @@ -493,7 +794,7 @@ bool rtklib_solver::get_PVT(const std::map& gnss_observables_ unsigned int used_sats = 0; for (unsigned int i = 0; i < MAXSAT; i++) { - if (rtk_.ssat[i].vsat[0] == 1) used_sats++; + if (rtk_.ssat[i].vs == 1) used_sats++; } std::vector azel; @@ -501,7 +802,7 @@ bool rtklib_solver::get_PVT(const std::map& gnss_observables_ unsigned int index_aux = 0; for (unsigned int i = 0; i < MAXSAT; i++) { - if (rtk_.ssat[i].vsat[0] == 1) + if (rtk_.ssat[i].vs == 1) { azel[2 * index_aux] = rtk_.ssat[i].azel[0]; azel[2 * index_aux + 1] = rtk_.ssat[i].azel[1]; @@ -559,73 +860,73 @@ bool rtklib_solver::get_PVT(const std::map& gnss_observables_ uint32_t tmp_uint32; // TOW tmp_uint32 = gnss_observables_map.begin()->second.TOW_at_current_symbol_ms; - d_dump_file.write(reinterpret_cast(&tmp_uint32), sizeof(uint32_t)); + d_dump_file.write(reinterpret_cast(&tmp_uint32), sizeof(uint32_t)); // WEEK tmp_uint32 = adjgpsweek(nav_data.eph[0].week); - d_dump_file.write(reinterpret_cast(&tmp_uint32), sizeof(uint32_t)); + d_dump_file.write(reinterpret_cast(&tmp_uint32), sizeof(uint32_t)); // PVT GPS time tmp_double = gnss_observables_map.begin()->second.RX_time; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // User clock offset [s] tmp_double = rx_position_and_time(3); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // ECEF POS X,Y,X [m] + ECEF VEL X,Y,X [m/s] (6 x double) tmp_double = pvt_sol.rr[0]; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = pvt_sol.rr[1]; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = pvt_sol.rr[2]; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = pvt_sol.rr[3]; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = pvt_sol.rr[4]; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = pvt_sol.rr[5]; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // position variance/covariance (m^2) {c_xx,c_yy,c_zz,c_xy,c_yz,c_zx} (6 x double) tmp_double = pvt_sol.qr[0]; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = pvt_sol.qr[1]; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = pvt_sol.qr[2]; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = pvt_sol.qr[3]; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = pvt_sol.qr[4]; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = pvt_sol.qr[5]; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // GEO user position Latitude [deg] tmp_double = get_latitude(); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // GEO user position Longitude [deg] tmp_double = get_longitude(); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // GEO user position Height [m] tmp_double = get_height(); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // NUMBER OF VALID SATS - d_dump_file.write(reinterpret_cast(&pvt_sol.ns), sizeof(uint8_t)); + d_dump_file.write(reinterpret_cast(&pvt_sol.ns), sizeof(uint8_t)); // RTKLIB solution status - d_dump_file.write(reinterpret_cast(&pvt_sol.stat), sizeof(uint8_t)); + d_dump_file.write(reinterpret_cast(&pvt_sol.stat), sizeof(uint8_t)); // RTKLIB solution type (0:xyz-ecef,1:enu-baseline) - d_dump_file.write(reinterpret_cast(&pvt_sol.type), sizeof(uint8_t)); + d_dump_file.write(reinterpret_cast(&pvt_sol.type), sizeof(uint8_t)); // AR ratio factor for validation - d_dump_file.write(reinterpret_cast(&pvt_sol.ratio), sizeof(float)); + d_dump_file.write(reinterpret_cast(&pvt_sol.ratio), sizeof(float)); // AR ratio threshold for validation - d_dump_file.write(reinterpret_cast(&pvt_sol.thres), sizeof(float)); + d_dump_file.write(reinterpret_cast(&pvt_sol.thres), sizeof(float)); // GDOP / PDOP/ HDOP/ VDOP - d_dump_file.write(reinterpret_cast(&dop_[0]), sizeof(double)); - d_dump_file.write(reinterpret_cast(&dop_[1]), sizeof(double)); - d_dump_file.write(reinterpret_cast(&dop_[2]), sizeof(double)); - d_dump_file.write(reinterpret_cast(&dop_[3]), sizeof(double)); + d_dump_file.write(reinterpret_cast(&dop_[0]), sizeof(double)); + d_dump_file.write(reinterpret_cast(&dop_[1]), sizeof(double)); + d_dump_file.write(reinterpret_cast(&dop_[2]), sizeof(double)); + d_dump_file.write(reinterpret_cast(&dop_[3]), sizeof(double)); } - catch (const std::ifstream::failure& e) + catch (const std::ifstream::failure &e) { LOG(WARNING) << "Exception writing RTKLIB dump file " << e.what(); } diff --git a/src/algorithms/PVT/libs/rtklib_solver.h b/src/algorithms/PVT/libs/rtklib_solver.h index df9dd9ab5..b584c4826 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.h +++ b/src/algorithms/PVT/libs/rtklib_solver.h @@ -60,6 +60,7 @@ #include "gps_navigation_message.h" #include "gps_cnav_navigation_message.h" #include "glonass_gnav_navigation_message.h" +#include "galileo_almanac.h" #include "gnss_synchro.h" #include "pvt_solution.h" #include @@ -76,14 +77,16 @@ private: rtk_t rtk_; std::string d_dump_filename; std::ofstream d_dump_file; + bool save_matfile(); bool d_flag_dump_enabled; + bool d_flag_dump_mat_enabled; int d_nchannels; // Number of available channels for positioning double dop_[4]; public: sol_t pvt_sol; - rtklib_solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, rtk_t& rtk); + rtklib_solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, bool flag_dump_to_mat, rtk_t& rtk); ~rtklib_solver(); bool get_PVT(const std::map& gnss_observables_map, bool flag_averaging); @@ -99,10 +102,11 @@ public: Galileo_Utc_Model galileo_utc_model; Galileo_Iono galileo_iono; - Galileo_Almanac galileo_almanac; + std::map galileo_almanac_map; Gps_Utc_Model gps_utc_model; Gps_Iono gps_iono; + std::map gps_almanac_map; Gps_CNAV_Iono gps_cnav_iono; Gps_CNAV_Utc_Model gps_cnav_utc_model; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc index 60d19ad08..0c451be34 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc @@ -40,6 +40,9 @@ using google::LogMessage; +void GalileoE1Pcps8msAmbiguousAcquisition::stop_acquisition() +{ +} GalileoE1Pcps8msAmbiguousAcquisition::GalileoE1Pcps8msAmbiguousAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.h index 5658aa06c..d64c0f28b 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.h @@ -122,6 +122,12 @@ public: * \brief Restart acquisition algorithm */ void reset() override; + + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + void set_state(int state __attribute__((unused))) override{}; private: diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index 065da5193..7efab9681 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -42,6 +42,10 @@ using google::LogMessage; +void GalileoE1PcpsAmbiguousAcquisition::stop_acquisition() +{ +} + GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -49,7 +53,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( Acq_Conf acq_parameters; configuration_ = configuration; std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "./data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; DLOG(INFO) << "role " << role; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h index 7390758d1..657f03064 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h @@ -131,6 +131,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc index c4e5eb843..d0fc0bd5d 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc @@ -39,9 +39,12 @@ #include - using google::LogMessage; +void GalileoE1PcpsAmbiguousAcquisitionFpga::stop_acquisition() +{ +} + GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -49,12 +52,14 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( //printf("top acq constructor start\n"); pcpsconf_fpga_t acq_parameters; configuration_ = configuration; + std::string default_item_type = "cshort"; std::string default_dump_filename = "./data/acquisition.dat"; + DLOG(INFO) << "role " << role; -// item_type_ = configuration_->property(role + ".item_type", default_item_type); + // item_type_ = configuration_->property(role + ".item_type", default_item_type); long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000); long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); @@ -73,10 +78,10 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( //if_ = configuration_->property(role + ".if", 0); //acq_parameters.freq = if_; - // dump_ = configuration_->property(role + ".dump", false); - // acq_parameters.dump = dump_; - // blocking_ = configuration_->property(role + ".blocking", true); -// acq_parameters.blocking = blocking_; + // dump_ = configuration_->property(role + ".dump", false); + // acq_parameters.dump = dump_; + // blocking_ = configuration_->property(role + ".blocking", true); + // acq_parameters.blocking = blocking_; doppler_max_ = configuration_->property(role + ".doppler_max", 5000); if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; acq_parameters.doppler_max = doppler_max_; @@ -85,16 +90,16 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 4); acq_parameters.sampled_ms = sampled_ms; - // bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); - // acq_parameters.bit_transition_flag = bit_transition_flag_; - // use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions - // acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; + // bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); + // acq_parameters.bit_transition_flag = bit_transition_flag_; + // use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions + // acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false); //will be true in future versions - // max_dwells_ = configuration_->property(role + ".max_dwells", 1); - // acq_parameters.max_dwells = max_dwells_; - // dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); - // acq_parameters.dump_filename = dump_filename_; + // max_dwells_ = configuration_->property(role + ".max_dwells", 1); + // acq_parameters.max_dwells = max_dwells_; + // dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); + // acq_parameters.dump_filename = dump_filename_; //--- Find number of samples per spreading code (4 ms) ----------------- unsigned int code_length = static_cast(std::round(static_cast(fs_in) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); //acq_parameters.samples_per_code = code_length_; @@ -102,10 +107,10 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( //acq_parameters.samples_per_ms = samples_per_ms; //unsigned int vector_length = sampled_ms * samples_per_ms; -// if (bit_transition_flag_) -// { -// vector_length_ *= 2; -// } + // if (bit_transition_flag_) + // { + // vector_length_ *= 2; + // } //printf("fs_in = %d\n", fs_in); //printf("Galileo_E1_B_CODE_LENGTH_CHIPS = %f\n", Galileo_E1_B_CODE_LENGTH_CHIPS); @@ -122,23 +127,24 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( std::string default_device_name = "/dev/uio0"; std::string device_name = configuration_->property(role + ".devicename", default_device_name); acq_parameters.device_name = device_name; - acq_parameters.samples_per_ms = nsamples_total/sampled_ms; + acq_parameters.samples_per_ms = nsamples_total / sampled_ms; acq_parameters.samples_per_code = nsamples_total; acq_parameters.excludelimit = static_cast(std::round(static_cast(fs_in) / Galileo_E1_CODE_CHIP_RATE_HZ)); // compute all the GALILEO E1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time // a channel is assigned) gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT - std::complex* code = new std::complex[nsamples_total]; // buffer for the local code + std::complex* code = new std::complex[nsamples_total]; // buffer for the local code gr_complex* fft_codes_padded = static_cast(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_all_fft_codes_ = new lv_16sc_t[nsamples_total * Galileo_E1_NUMBER_OF_CODES]; // memory containing all the possible fft codes for PRN 0 to 32 - float max; // temporary maxima search + float max; // temporary maxima search //int tmp_re, tmp_im; for (unsigned int PRN = 1; PRN <= Galileo_E1_NUMBER_OF_CODES; PRN++) { + //code_ = new gr_complex[vector_length_]; bool cboc = false; // cboc is set to 0 when using the FPGA @@ -272,23 +278,24 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( // fclose(fid2); + } -// for (unsigned int PRN = 1; PRN <= Galileo_E1_NUMBER_OF_CODES; PRN++) -// { -// // debug -// char filename2[25]; -// FILE *fid2; -// sprintf(filename2,"fft_gal_prn%d_norm_last.txt", PRN); -// fid2 = fopen(filename2, "w"); -// for (unsigned int kk=0;kk< nsamples_total; kk++) -// { -// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real()); -// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag()); -// } -// fclose(fid2); -// } + // for (unsigned int PRN = 1; PRN <= Galileo_E1_NUMBER_OF_CODES; PRN++) + // { + // // debug + // char filename2[25]; + // FILE *fid2; + // sprintf(filename2,"fft_gal_prn%d_norm_last.txt", PRN); + // fid2 = fopen(filename2, "w"); + // for (unsigned int kk=0;kk< nsamples_total; kk++) + // { + // fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real()); + // fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag()); + // } + // fclose(fid2); + // } //acq_parameters @@ -304,14 +311,14 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; -// stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); -// DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; + // stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); + // DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; -// if (item_type_.compare("cbyte") == 0) -// { -// cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); -// float_to_complex_ = gr::blocks::float_to_complex::make(); -// } + // if (item_type_.compare("cbyte") == 0) + // { + // cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); + // float_to_complex_ = gr::blocks::float_to_complex::make(); + // } channel_ = 0; //threshold_ = 0.0; @@ -345,22 +352,22 @@ void GalileoE1PcpsAmbiguousAcquisitionFpga::set_threshold(float threshold) // the .pfa parameter and the threshold calculation is only used for the CFAR algorithm. // We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such. -// float pfa = configuration_->property(role_ + boost::lexical_cast(channel_) + ".pfa", 0.0); -// -// if (pfa == 0.0) pfa = configuration_->property(role_ + ".pfa", 0.0); -// -// if (pfa == 0.0) -// { -// threshold_ = threshold; -// } -// else -// { -// threshold_ = calculate_threshold(pfa); -// } + // float pfa = configuration_->property(role_ + boost::lexical_cast(channel_) + ".pfa", 0.0); + // + // if (pfa == 0.0) pfa = configuration_->property(role_ + ".pfa", 0.0); + // + // if (pfa == 0.0) + // { + // threshold_ = threshold; + // } + // else + // { + // threshold_ = calculate_threshold(pfa); + // } DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; acquisition_fpga_->set_threshold(threshold); -// acquisition_fpga_->set_threshold(threshold_); + // acquisition_fpga_->set_threshold(threshold_); //printf("top acq set threshold end\n"); } @@ -397,7 +404,7 @@ void GalileoE1PcpsAmbiguousAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_ signed int GalileoE1PcpsAmbiguousAcquisitionFpga::mag() { - // printf("top acq mag start\n"); + // printf("top acq mag start\n"); return acquisition_fpga_->mag(); //printf("top acq mag end\n"); } @@ -405,60 +412,60 @@ signed int GalileoE1PcpsAmbiguousAcquisitionFpga::mag() void GalileoE1PcpsAmbiguousAcquisitionFpga::init() { - // printf("top acq init start\n"); + // printf("top acq init start\n"); acquisition_fpga_->init(); - // printf("top acq init end\n"); + // printf("top acq init end\n"); //set_local_code(); } void GalileoE1PcpsAmbiguousAcquisitionFpga::set_local_code() { - // printf("top acq set local code start\n"); -// bool cboc = configuration_->property( -// "Acquisition" + boost::lexical_cast(channel_) + ".cboc", false); -// -// std::complex* code = new std::complex[code_length_]; -// -// if (acquire_pilot_ == true) -// { -// //set local signal generator to Galileo E1 pilot component (1C) -// char pilot_signal[3] = "1C"; -// galileo_e1_code_gen_complex_sampled(code, pilot_signal, -// cboc, gnss_synchro_->PRN, fs_in_, 0, false); -// } -// else -// { -// galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, -// cboc, gnss_synchro_->PRN, fs_in_, 0, false); -// } -// -// -// for (unsigned int i = 0; i < sampled_ms_ / 4; i++) -// { -// memcpy(&(code_[i * code_length_]), code, sizeof(gr_complex) * code_length_); -// } + // printf("top acq set local code start\n"); + // bool cboc = configuration_->property( + // "Acquisition" + boost::lexical_cast(channel_) + ".cboc", false); + // + // std::complex* code = new std::complex[code_length_]; + // + // if (acquire_pilot_ == true) + // { + // //set local signal generator to Galileo E1 pilot component (1C) + // char pilot_signal[3] = "1C"; + // galileo_e1_code_gen_complex_sampled(code, pilot_signal, + // cboc, gnss_synchro_->PRN, fs_in_, 0, false); + // } + // else + // { + // galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, + // cboc, gnss_synchro_->PRN, fs_in_, 0, false); + // } + // + // + // for (unsigned int i = 0; i < sampled_ms_ / 4; i++) + // { + // memcpy(&(code_[i * code_length_]), code, sizeof(gr_complex) * code_length_); + // } //acquisition_fpga_->set_local_code(code_); acquisition_fpga_->set_local_code(); -// delete[] code; - // printf("top acq set local code end\n"); + // delete[] code; + // printf("top acq set local code end\n"); } void GalileoE1PcpsAmbiguousAcquisitionFpga::reset() { - // printf("top acq reset start\n"); + // printf("top acq reset start\n"); acquisition_fpga_->set_active(true); - // printf("top acq reset end\n"); + // printf("top acq reset end\n"); } void GalileoE1PcpsAmbiguousAcquisitionFpga::set_state(int state) { - // printf("top acq set state start\n"); + // printf("top acq set state start\n"); acquisition_fpga_->set_state(state); - // printf("top acq set state end\n"); + // printf("top acq set state end\n"); } @@ -509,26 +516,26 @@ void GalileoE1PcpsAmbiguousAcquisitionFpga::read_fpga_total_scale_factor(uint32_ void GalileoE1PcpsAmbiguousAcquisitionFpga::connect(gr::top_block_sptr top_block) { - // printf("top acq connect\n"); -// if (item_type_.compare("gr_complex") == 0) -// { -// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); -// } -// else if (item_type_.compare("cshort") == 0) -// { -// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); -// } -// else if (item_type_.compare("cbyte") == 0) -// { -// top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); -// top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); -// top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); -// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); -// } -// else -// { -// LOG(WARNING) << item_type_ << " unknown acquisition item type"; -// } + // printf("top acq connect\n"); + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + // top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + // top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); + // top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } // nothing to connect } @@ -536,61 +543,60 @@ void GalileoE1PcpsAmbiguousAcquisitionFpga::connect(gr::top_block_sptr top_block void GalileoE1PcpsAmbiguousAcquisitionFpga::disconnect(gr::top_block_sptr top_block) { -// if (item_type_.compare("gr_complex") == 0) -// { -// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); -// } -// else if (item_type_.compare("cshort") == 0) -// { -// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); -// } -// else if (item_type_.compare("cbyte") == 0) -// { -// // Since a byte-based acq implementation is not available, -// // we just convert cshorts to gr_complex -// top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); -// top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); -// top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); -// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); -// } -// else -// { -// LOG(WARNING) << item_type_ << " unknown acquisition item type"; -// } + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // // Since a byte-based acq implementation is not available, + // // we just convert cshorts to gr_complex + // top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + // top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + // top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); + // top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } // nothing to disconnect - // printf("top acq disconnect\n"); + // printf("top acq disconnect\n"); } gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_left_block() { - // printf("top acq get left block start\n"); -// if (item_type_.compare("gr_complex") == 0) -// { -// return stream_to_vector_; -// } -// else if (item_type_.compare("cshort") == 0) -// { -// return stream_to_vector_; -// } -// else if (item_type_.compare("cbyte") == 0) -// { -// return cbyte_to_float_x2_; -// } -// else -// { -// LOG(WARNING) << item_type_ << " unknown acquisition item type"; - return nullptr; -// } - // printf("top acq get left block end\n"); + // printf("top acq get left block start\n"); + // if (item_type_.compare("gr_complex") == 0) + // { + // return stream_to_vector_; + // } + // else if (item_type_.compare("cshort") == 0) + // { + // return stream_to_vector_; + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // return cbyte_to_float_x2_; + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + return nullptr; + // } + // printf("top acq get left block end\n"); } gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_right_block() { - // printf("top acq get right block start\n"); + // printf("top acq get right block start\n"); return acquisition_fpga_; - // printf("top acq get right block end\n"); + // printf("top acq get right block end\n"); } - diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h index 7dea9e459..ba8a6662d 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h @@ -156,6 +156,11 @@ public: */ void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor); + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; //pcps_acquisition_sptr acquisition_; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc index 625c92396..46a3b1974 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc @@ -40,6 +40,10 @@ using google::LogMessage; +void GalileoE1PcpsCccwsrAmbiguousAcquisition::stop_acquisition() +{ +} + GalileoE1PcpsCccwsrAmbiguousAcquisition::GalileoE1PcpsCccwsrAmbiguousAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.h index 54b5ee54e..47c19becb 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.h @@ -125,6 +125,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_cccwsr_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc index 34c56ddf9..36ed925df 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc @@ -40,6 +40,10 @@ using google::LogMessage; +void GalileoE1PcpsQuickSyncAmbiguousAcquisition::stop_acquisition() +{ +} + GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.h index 5bfa06ca2..1d7b25880 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.h @@ -129,6 +129,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_quicksync_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc index 2e5bd5684..4d7038364 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc @@ -40,6 +40,10 @@ using google::LogMessage; +void GalileoE1PcpsTongAmbiguousAcquisition::stop_acquisition() +{ +} + GalileoE1PcpsTongAmbiguousAcquisition::GalileoE1PcpsTongAmbiguousAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.h index a47a22329..8524fc8d1 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.h @@ -128,6 +128,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_tong_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc index 78d95d36e..e24970d63 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc @@ -46,6 +46,10 @@ using google::LogMessage; +void GalileoE5aNoncoherentIQAcquisitionCaf::stop_acquisition() +{ +} + GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h index 823bdc1ff..6beed3472 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h @@ -131,6 +131,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc index cd138e12e..2bd081e3e 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc @@ -42,13 +42,17 @@ using google::LogMessage; +void GalileoE5aPcpsAcquisition::stop_acquisition() +{ +} + GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "../data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; DLOG(INFO) << "Role " << role; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h index 344e8f5b6..49099cd42 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h @@ -122,6 +122,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: float calculate_threshold(float pfa); diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc index 66ceca8a6..d30a30500 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc @@ -39,15 +39,16 @@ #include - - - using google::LogMessage; +void GalileoE5aPcpsAcquisitionFpga::stop_acquisition() +{ +} + GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - //printf("creating the E5A acquisition"); + //printf("creating the E5A acquisition"); pcpsconf_fpga_t acq_parameters; configuration_ = configuration; std::string default_item_type = "cshort"; @@ -109,7 +110,7 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf std::string default_device_name = "/dev/uio0"; std::string device_name = configuration_->property(role + ".devicename", default_device_name); acq_parameters.device_name = device_name; - acq_parameters.samples_per_ms = nsamples_total/sampled_ms; + acq_parameters.samples_per_ms = nsamples_total / sampled_ms; acq_parameters.samples_per_code = nsamples_total; //vector_length_ = code_length_ * sampled_ms_; @@ -117,10 +118,10 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf // compute all the GALILEO E5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time // a channel is assigned) gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT - std::complex* code = new std::complex[nsamples_total]; // buffer for the local code + std::complex* code = new std::complex[nsamples_total]; // buffer for the local code gr_complex* fft_codes_padded = static_cast(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_all_fft_codes_ = new lv_16sc_t[nsamples_total * Galileo_E5a_NUMBER_OF_CODES]; // memory containing all the possible fft codes for PRN 0 to 32 - float max; // temporary maxima search + float max; // temporary maxima search //printf("creating the E5A acquisition CONT"); //printf("nsamples_total = %d\n", nsamples_total); @@ -155,16 +156,16 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf // fill in zero padding for (int s = 2*code_length; s < nsamples_total; s++) { - code[s] = std::complex(static_cast(0,0)); + code[s] = std::complex(static_cast(0, 0)); //code[s] = 0; } - memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer + memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer fft_if->execute(); // Run the FFT of local code volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values - max = 0; // initialize maximum value - for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima + max = 0; // initialize maximum value + for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima { if (std::abs(fft_codes_padded[i].real()) > max) { @@ -180,7 +181,6 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 5) - 1) / max)), static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 5) - 1) / max))); } - } @@ -193,19 +193,19 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf //code_ = new gr_complex[vector_length_]; -// if (item_type_.compare("gr_complex") == 0) -// { -// item_size_ = sizeof(gr_complex); -// } -// else if (item_type_.compare("cshort") == 0) -// { -// item_size_ = sizeof(lv_16sc_t); -// } -// else -// { -// item_size_ = sizeof(gr_complex); -// LOG(WARNING) << item_type_ << " unknown acquisition item type"; -// } + // if (item_type_.compare("gr_complex") == 0) + // { + // item_size_ = sizeof(gr_complex); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // item_size_ = sizeof(lv_16sc_t); + // } + // else + // { + // item_size_ = sizeof(gr_complex); + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } //acq_parameters.it_size = item_size_; //acq_parameters.samples_per_code = code_length_; //acq_parameters.samples_per_ms = code_length_; @@ -248,22 +248,22 @@ void GalileoE5aPcpsAcquisitionFpga::set_channel(unsigned int channel) void GalileoE5aPcpsAcquisitionFpga::set_threshold(float threshold) { -// float pfa = configuration_->property(role_ + boost::lexical_cast(channel_) + ".pfa", 0.0); -// -// if (pfa == 0.0) -// { -// pfa = configuration_->property(role_ + ".pfa", 0.0); -// } -// -// if (pfa == 0.0) -// { -// threshold_ = threshold; -// } -// -// else -// { -// threshold_ = calculate_threshold(pfa); -// } + // float pfa = configuration_->property(role_ + boost::lexical_cast(channel_) + ".pfa", 0.0); + // + // if (pfa == 0.0) + // { + // pfa = configuration_->property(role_ + ".pfa", 0.0); + // } + // + // if (pfa == 0.0) + // { + // threshold_ = threshold; + // } + // + // else + // { + // threshold_ = calculate_threshold(pfa); + // } DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; @@ -312,32 +312,32 @@ void GalileoE5aPcpsAcquisitionFpga::init() void GalileoE5aPcpsAcquisitionFpga::set_local_code() { -// gr_complex* code = new gr_complex[code_length_]; -// char signal_[3]; -// -// if (acq_iq_) -// { -// strcpy(signal_, "5X"); -// } -// else if (acq_pilot_) -// { -// strcpy(signal_, "5Q"); -// } -// else -// { -// strcpy(signal_, "5I"); -// } -// -// galileo_e5_a_code_gen_complex_sampled(code, signal_, gnss_synchro_->PRN, fs_in_, 0); -// -// for (unsigned int i = 0; i < sampled_ms_; i++) -// { -// memcpy(code_ + (i * code_length_), code, sizeof(gr_complex) * code_length_); -// } + // gr_complex* code = new gr_complex[code_length_]; + // char signal_[3]; + // + // if (acq_iq_) + // { + // strcpy(signal_, "5X"); + // } + // else if (acq_pilot_) + // { + // strcpy(signal_, "5Q"); + // } + // else + // { + // strcpy(signal_, "5I"); + // } + // + // galileo_e5_a_code_gen_complex_sampled(code, signal_, gnss_synchro_->PRN, fs_in_, 0); + // + // for (unsigned int i = 0; i < sampled_ms_; i++) + // { + // memcpy(code_ + (i * code_length_), code, sizeof(gr_complex) * code_length_); + // } //acquisition_->set_local_code(code_); acquisition_fpga_->set_local_code(); -// delete[] code; + // delete[] code; } @@ -400,35 +400,35 @@ void GalileoE5aPcpsAcquisitionFpga::read_fpga_total_scale_factor(uint32_t *total void GalileoE5aPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) { -// if (item_type_.compare("gr_complex") == 0) -// { -// top_block->connect(stream_to_vector_, 0, acquisition_, 0); -// } -// else if (item_type_.compare("cshort") == 0) -// { -// top_block->connect(stream_to_vector_, 0, acquisition_, 0); -// } -// else -// { -// LOG(WARNING) << item_type_ << " unknown acquisition item type"; -// } + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } } void GalileoE5aPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) { -// if (item_type_.compare("gr_complex") == 0) -// { -// top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); -// } -// else if (item_type_.compare("cshort") == 0) -// { -// top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); -// } -// else -// { -// LOG(WARNING) << item_type_ << " unknown acquisition item type"; -// } + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } } diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h index b2791a7d9..dbf593380 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h @@ -144,6 +144,11 @@ public: */ void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor); + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: //float calculate_threshold(float pfa); diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc index 90cfc7014..5b3d1c531 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc @@ -43,6 +43,10 @@ using google::LogMessage; +void GlonassL1CaPcpsAcquisition::stop_acquisition() +{ +} + GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h index 6f4947917..1b519f91e 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h @@ -131,6 +131,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; diff --git a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc index 86052d6f2..06ef7aae6 100644 --- a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc @@ -42,6 +42,10 @@ using google::LogMessage; +void GlonassL2CaPcpsAcquisition::stop_acquisition() +{ +} + GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h index f25412d2b..b679f4c26 100644 --- a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h @@ -130,6 +130,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc index b91223b06..30d7aa42d 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GpsL1CaPcpsAcquisition::stop_acquisition() +{ +} + GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -52,7 +56,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "./data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; DLOG(INFO) << "role " << role; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h index 2a4126bd8..011bb96bf 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h @@ -135,6 +135,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc index 68d67dac8..dd69ed24f 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc @@ -42,12 +42,16 @@ using google::LogMessage; +void GpsL1CaPcpsAcquisitionFineDoppler::stop_acquisition() +{ +} + GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "./data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; DLOG(INFO) << "role " << role; Acq_Conf acq_parameters = Acq_Conf(); diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.h index 5fac62916..338ea683a 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.h @@ -126,6 +126,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: pcps_acquisition_fine_doppler_cc_sptr acquisition_cc_; size_t item_size_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc index 033f17015..d7461b287 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc @@ -48,6 +48,10 @@ using google::LogMessage; +void GpsL1CaPcpsAcquisitionFpga::stop_acquisition() +{ +} + GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h index 9231f3a70..60fdab730 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h @@ -154,6 +154,11 @@ public: */ void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor); + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_fpga_sptr acquisition_fpga_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc index 528a9a3f2..da1377ac2 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc @@ -42,6 +42,10 @@ using google::LogMessage; +void GpsL1CaPcpsAssistedAcquisition::stop_acquisition() +{ +} + GpsL1CaPcpsAssistedAcquisition::GpsL1CaPcpsAssistedAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h index 83218aac4..ca650bc77 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h @@ -122,6 +122,11 @@ public: void reset() override; void set_state(int state __attribute__((unused))) override{}; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: pcps_assisted_acquisition_cc_sptr acquisition_cc_; size_t item_size_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc index 7c5b84f63..1037a1778 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc @@ -40,6 +40,10 @@ using google::LogMessage; +void GpsL1CaPcpsOpenClAcquisition::stop_acquisition() +{ +} + GpsL1CaPcpsOpenClAcquisition::GpsL1CaPcpsOpenClAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.h index 7d3e7b58e..0c6c21f49 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.h @@ -124,6 +124,11 @@ public: void reset() override; void set_state(int state __attribute__((unused))) override{}; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_opencl_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc index b25be59e0..888d44586 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc @@ -41,6 +41,10 @@ using google::LogMessage; +void GpsL1CaPcpsQuickSyncAcquisition::stop_acquisition() +{ +} + GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.h index f38ee7055..c35f97370 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.h @@ -130,6 +130,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_quicksync_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc index e676d5d9c..5c55d802a 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc @@ -40,6 +40,10 @@ using google::LogMessage; +void GpsL1CaPcpsTongAcquisition::stop_acquisition() +{ +} + GpsL1CaPcpsTongAcquisition::GpsL1CaPcpsTongAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.h index b09f6cde0..562d63e39 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.h @@ -129,6 +129,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_tong_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc index 806adad4e..32b426777 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc @@ -43,6 +43,10 @@ using google::LogMessage; +void GpsL2MPcpsAcquisition::stop_acquisition() +{ +} + GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -50,7 +54,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "./data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; LOG(INFO) << "role " << role; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.h b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.h index f1e57b9b5..27c463cf3 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.h @@ -133,6 +133,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc index 733f3cea9..db53d3815 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc @@ -43,6 +43,10 @@ using google::LogMessage; +void GpsL2MPcpsAcquisitionFpga::stop_acquisition() +{ +} + GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -51,7 +55,7 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( pcpsconf_fpga_t acq_parameters; configuration_ = configuration; std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "./data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; LOG(INFO) << "role " << role; @@ -93,7 +97,7 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( std::string default_device_name = "/dev/uio0"; std::string device_name = configuration_->property(role + ".devicename", default_device_name); acq_parameters.device_name = device_name; - acq_parameters.samples_per_ms = nsamples_total/acq_parameters.sampled_ms; + acq_parameters.samples_per_ms = nsamples_total / acq_parameters.sampled_ms; //acq_parameters.samples_per_ms = static_cast(std::round(static_cast(fs_in_) * 0.001)); acq_parameters.samples_per_code = nsamples_total; @@ -111,10 +115,10 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( // fill in zero padding for (int s = code_length; s < nsamples_total; s++) { - code[s] = std::complex(static_cast(0,0)); + code[s] = std::complex(static_cast(0, 0)); //code[s] = 0; } - memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer + memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer fft_if->execute(); // Run the FFT of local code volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values max = 0; // initialize maximum value @@ -134,7 +138,6 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); } - } //acq_parameters @@ -153,26 +156,23 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( gnss_synchro_ = 0; + // vector_length_ = code_length_; + // + // if (bit_transition_flag_) + // { + // vector_length_ *= 2; + // } - - -// vector_length_ = code_length_; -// -// if (bit_transition_flag_) -// { -// vector_length_ *= 2; -// } - -// code_ = new gr_complex[vector_length_]; -// -// if (item_type_.compare("cshort") == 0) -// { -// item_size_ = sizeof(lv_16sc_t); -// } -// else -// { -// item_size_ = sizeof(gr_complex); -// } + // code_ = new gr_complex[vector_length_]; + // + // if (item_type_.compare("cshort") == 0) + // { + // item_size_ = sizeof(lv_16sc_t); + // } + // else + // { + // item_size_ = sizeof(gr_complex); + // } //acq_parameters.samples_per_ms = static_cast(std::round(static_cast(fs_in_) * 0.001)); //acq_parameters.samples_per_code = code_length_; //acq_parameters.it_size = item_size_; @@ -183,19 +183,19 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( //acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; -// stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); -// DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; -// -// if (item_type_.compare("cbyte") == 0) -// { -// cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); -// float_to_complex_ = gr::blocks::float_to_complex::make(); -// } + // stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); + // DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; + // + // if (item_type_.compare("cbyte") == 0) + // { + // cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); + // float_to_complex_ = gr::blocks::float_to_complex::make(); + // } -// channel_ = 0; + // channel_ = 0; threshold_ = 0.0; -// doppler_step_ = 0; -// gnss_synchro_ = 0; + // doppler_step_ = 0; + // gnss_synchro_ = 0; } @@ -215,20 +215,20 @@ void GpsL2MPcpsAcquisitionFpga::set_channel(unsigned int channel) void GpsL2MPcpsAcquisitionFpga::set_threshold(float threshold) { -// float pfa = configuration_->property(role_ + boost::lexical_cast(channel_) + ".pfa", 0.0); -// -// if (pfa == 0.0) -// { -// pfa = configuration_->property(role_ + ".pfa", 0.0); -// } -// if (pfa == 0.0) -// { -// threshold_ = threshold; -// } -// else -// { -// threshold_ = calculate_threshold(pfa); -// } + // float pfa = configuration_->property(role_ + boost::lexical_cast(channel_) + ".pfa", 0.0); + // + // if (pfa == 0.0) + // { + // pfa = configuration_->property(role_ + ".pfa", 0.0); + // } + // if (pfa == 0.0) + // { + // threshold_ = threshold; + // } + // else + // { + // threshold_ = calculate_threshold(pfa); + // } DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; @@ -317,25 +317,25 @@ void GpsL2MPcpsAcquisitionFpga::set_state(int state) void GpsL2MPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) { -// if (item_type_.compare("gr_complex") == 0) -// { -// top_block->connect(stream_to_vector_, 0, acquisition_, 0); -// } -// else if (item_type_.compare("cshort") == 0) -// { -// top_block->connect(stream_to_vector_, 0, acquisition_, 0); -// } -// else if (item_type_.compare("cbyte") == 0) -// { -// top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); -// top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); -// top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); -// top_block->connect(stream_to_vector_, 0, acquisition_, 0); -// } -// else -// { -// LOG(WARNING) << item_type_ << " unknown acquisition item type"; -// } + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + // top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + // top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); + // top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } // nothing to connect } @@ -343,27 +343,27 @@ void GpsL2MPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) void GpsL2MPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) { -// if (item_type_.compare("gr_complex") == 0) -// { -// top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); -// } -// else if (item_type_.compare("cshort") == 0) -// { -// top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); -// } -// else if (item_type_.compare("cbyte") == 0) -// { -// // Since a byte-based acq implementation is not available, -// // we just convert cshorts to gr_complex -// top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); -// top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); -// top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); -// top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); -// } -// else -// { -// LOG(WARNING) << item_type_ << " unknown acquisition item type"; -// } + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // // Since a byte-based acq implementation is not available, + // // we just convert cshorts to gr_complex + // top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + // top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + // top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); + // top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } // nothing to disconnect } @@ -371,23 +371,23 @@ void GpsL2MPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) gr::basic_block_sptr GpsL2MPcpsAcquisitionFpga::get_left_block() { -// if (item_type_.compare("gr_complex") == 0) -// { -// return stream_to_vector_; -// } -// else if (item_type_.compare("cshort") == 0) -// { -// return stream_to_vector_; -// } -// else if (item_type_.compare("cbyte") == 0) -// { -// return cbyte_to_float_x2_; -// } -// else -// { -// LOG(WARNING) << item_type_ << " unknown acquisition item type"; -// return nullptr; -// } + // if (item_type_.compare("gr_complex") == 0) + // { + // return stream_to_vector_; + // } + // else if (item_type_.compare("cshort") == 0) + // { + // return stream_to_vector_; + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // return cbyte_to_float_x2_; + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // return nullptr; + // } return nullptr; } diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h index 9f7912628..b9aba8787 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h @@ -134,6 +134,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; //pcps_acquisition_sptr acquisition_; diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc index a0b072a31..36d6e4f7a 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc @@ -43,6 +43,10 @@ using google::LogMessage; +void GpsL5iPcpsAcquisition::stop_acquisition() +{ +} + GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -50,7 +54,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "./data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; LOG(INFO) << "role " << role; diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h index 2b4d86eeb..3c4d2ad46 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h @@ -133,6 +133,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc index 4d124978a..8a166f44e 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc @@ -43,12 +43,16 @@ using google::LogMessage; +void GpsL5iPcpsAcquisitionFpga::stop_acquisition() +{ +} + GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - //printf("L5 ACQ CLASS CREATED\n"); - pcpsconf_fpga_t acq_parameters; + //printf("L5 ACQ CLASS CREATED\n"); + pcpsconf_fpga_t acq_parameters; configuration_ = configuration; std::string default_item_type = "cshort"; std::string default_dump_filename = "./data/acquisition.dat"; @@ -120,7 +124,7 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( //printf("L5 ACQ CLASS MID 1 vector_length = %d\n", vector_length); - float max; // temporary maxima search + float max; // temporary maxima search for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) { //printf("L5 ACQ CLASS processing PRN = %d\n", PRN); @@ -180,49 +184,49 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( delete[] code; delete fft_if; delete[] fft_codes_padded; -// vector_length_ = code_length_; -// -// if (bit_transition_flag_) -// { -// vector_length_ *= 2; -// } -// -// code_ = new gr_complex[vector_length_]; -// -// if (item_type_.compare("cshort") == 0) -// { -// item_size_ = sizeof(lv_16sc_t); -// } -// else -// { -// item_size_ = sizeof(gr_complex); -// } -// acq_parameters.samples_per_code = code_length_; -// acq_parameters.samples_per_ms = code_length_; -// acq_parameters.it_size = item_size_; + // vector_length_ = code_length_; + // + // if (bit_transition_flag_) + // { + // vector_length_ *= 2; + // } + // + // code_ = new gr_complex[vector_length_]; + // + // if (item_type_.compare("cshort") == 0) + // { + // item_size_ = sizeof(lv_16sc_t); + // } + // else + // { + // item_size_ = sizeof(gr_complex); + // } + // acq_parameters.samples_per_code = code_length_; + // acq_parameters.samples_per_ms = code_length_; + // acq_parameters.it_size = item_size_; //acq_parameters.sampled_ms = 1; -// acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); -// acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); -// acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); -// acquisition_fpga_ = pcps_make_acquisition(acq_parameters); -// DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; + // acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); + // acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); + // acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); + // acquisition_fpga_ = pcps_make_acquisition(acq_parameters); + // DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; acq_parameters.total_block_exp = 9; acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; -// stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); -// DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; -// -// if (item_type_.compare("cbyte") == 0) -// { -// cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); -// float_to_complex_ = gr::blocks::float_to_complex::make(); -// } + // stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); + // DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; + // + // if (item_type_.compare("cbyte") == 0) + // { + // cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); + // float_to_complex_ = gr::blocks::float_to_complex::make(); + // } channel_ = 0; -// threshold_ = 0.0; + // threshold_ = 0.0; doppler_step_ = 0; gnss_synchro_ = 0; //printf("L5 ACQ CLASS FINISHED\n"); @@ -240,34 +244,32 @@ void GpsL5iPcpsAcquisitionFpga::set_channel(unsigned int channel) { channel_ = channel; acquisition_fpga_->set_channel(channel_); - } void GpsL5iPcpsAcquisitionFpga::set_threshold(float threshold) { -// float pfa = configuration_->property(role_ + boost::lexical_cast(channel_) + ".pfa", 0.0); -// -// if (pfa == 0.0) -// { -// pfa = configuration_->property(role_ + ".pfa", 0.0); -// } -// if (pfa == 0.0) -// { -// threshold_ = threshold; -// } -// else -// { -// threshold_ = calculate_threshold(pfa); -// } + // float pfa = configuration_->property(role_ + boost::lexical_cast(channel_) + ".pfa", 0.0); + // + // if (pfa == 0.0) + // { + // pfa = configuration_->property(role_ + ".pfa", 0.0); + // } + // if (pfa == 0.0) + // { + // threshold_ = threshold; + // } + // else + // { + // threshold_ = calculate_threshold(pfa); + // } -// DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; + // DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; // the .pfa parameter and the threshold calculation is only used for the CFAR algorithm. // We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such. DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; acquisition_fpga_->set_threshold(threshold); - } @@ -296,18 +298,18 @@ void GpsL5iPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) signed int GpsL5iPcpsAcquisitionFpga::mag() { - return acquisition_fpga_->mag(); + return acquisition_fpga_->mag(); } void GpsL5iPcpsAcquisitionFpga::init() { - acquisition_fpga_->init(); + acquisition_fpga_->init(); } void GpsL5iPcpsAcquisitionFpga::set_local_code() { - acquisition_fpga_->set_local_code(); + acquisition_fpga_->set_local_code(); } @@ -369,75 +371,75 @@ void GpsL5iPcpsAcquisitionFpga::read_fpga_total_scale_factor(uint32_t *total_sca void GpsL5iPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) { -// if (item_type_.compare("gr_complex") == 0) -// { -// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); -// } -// else if (item_type_.compare("cshort") == 0) -// { -// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); -// } -// else if (item_type_.compare("cbyte") == 0) -// { -// top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); -// top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); -// top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); -// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); -// } -// else -// { -// LOG(WARNING) << item_type_ << " unknown acquisition item type"; -// } + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + // top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + // top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); + // top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } // nothing to connect } void GpsL5iPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) { -// if (item_type_.compare("gr_complex") == 0) -// { -// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); -// } -// else if (item_type_.compare("cshort") == 0) -// { -// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); -// } -// else if (item_type_.compare("cbyte") == 0) -// { -// // Since a byte-based acq implementation is not available, -// // we just convert cshorts to gr_complex -// top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); -// top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); -// top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); -// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); -// } -// else -// { -// LOG(WARNING) << item_type_ << " unknown acquisition item type"; -// } + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // // Since a byte-based acq implementation is not available, + // // we just convert cshorts to gr_complex + // top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + // top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + // top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); + // top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } // nothing to disconnect } gr::basic_block_sptr GpsL5iPcpsAcquisitionFpga::get_left_block() { -// if (item_type_.compare("gr_complex") == 0) -// { -// return stream_to_vector_; -// } -// else if (item_type_.compare("cshort") == 0) -// { -// return stream_to_vector_; -// } -// else if (item_type_.compare("cbyte") == 0) -// { -// return cbyte_to_float_x2_; -// } -// else -// { -// LOG(WARNING) << item_type_ << " unknown acquisition item type"; -// return nullptr; -// } + // if (item_type_.compare("gr_complex") == 0) + // { + // return stream_to_vector_; + // } + // else if (item_type_.compare("cshort") == 0) + // { + // return stream_to_vector_; + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // return cbyte_to_float_x2_; + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // return nullptr; + // } return nullptr; } diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h index 1f9638e9d..5b25b0771 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h @@ -154,6 +154,11 @@ public: */ void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor); + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; //pcps_acquisition_sptr acquisition_; diff --git a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt index 327b1a927..bd1800d35 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt @@ -37,13 +37,13 @@ set(ACQ_GR_BLOCKS_HEADERS pcps_quicksync_acquisition_cc.h galileo_pcps_8ms_acquisition_cc.h galileo_e5a_noncoherent_iq_acquisition_caf_cc.h -) +) if(ENABLE_FPGA) set(ACQ_GR_BLOCKS_SOURCES ${ACQ_GR_BLOCKS_SOURCES} pcps_acquisition_fpga.cc) set(ACQ_GR_BLOCKS_HEADERS ${ACQ_GR_BLOCKS_HEADERS} pcps_acquisition_fpga.h) endif(ENABLE_FPGA) - + if(OPENCL_FOUND) set(ACQ_GR_BLOCKS_SOURCES ${ACQ_GR_BLOCKS_SOURCES} pcps_opencl_acquisition_cc.cc) set(ACQ_GR_BLOCKS_HEADERS ${ACQ_GR_BLOCKS_HEADERS} pcps_opencl_acquisition_cc.h) @@ -56,6 +56,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/core/receiver ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/libs ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${Boost_INCLUDE_DIRS} ${GLOG_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS} ${ARMADILLO_INCLUDE_DIRS} diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 034cbbd10..1bb4b39a7 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -36,6 +36,8 @@ #include "pcps_acquisition.h" #include "GPS_L1_CA.h" // for GPS_TWO_PI #include "GLONASS_L1_L2_CA.h" // for GLONASS_TWO_PI" +#include "gnss_sdr_create_directory.h" +#include #include #include #include @@ -136,8 +138,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu narrow_grid_ = arma::fmat(); d_step_two = false; d_num_doppler_bins_step2 = acq_parameters.num_doppler_bins_step2; - d_dump_number = 0LL; - d_dump_channel = acq_parameters.dump_channel; + d_samplesPerChip = acq_parameters.samples_per_chip; d_buffer_count = 0U; // todo: CFAR statistic not available for non-coherent integration @@ -149,9 +150,43 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu { d_use_CFAR_algorithm_flag = false; } + d_dump_number = 0LL; + d_dump_channel = acq_parameters.dump_channel; + d_dump = acq_parameters.dump; + d_dump_filename = acq_parameters.dump_filename; + if (d_dump) + { + std::string dump_path; + // Get path + if (d_dump_filename.find_last_of("/") != std::string::npos) + { + 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 = "acquisition"; + } + // 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 + boost::filesystem::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 Acquisition block. Wrong permissions?" << std::endl; + d_dump = false; + } + } } - pcps_acquisition::~pcps_acquisition() { if (d_num_doppler_bins > 0) @@ -303,7 +338,7 @@ void pcps_acquisition::init() d_worker_active = false; - if (acq_parameters.dump) + if (d_dump) { uint32_t effective_fft_size = (acq_parameters.bit_transition_flag ? (d_fft_size / 2) : d_fft_size); grid_ = arma::fmat(effective_fft_size, d_num_doppler_bins, arma::fill::zeros); @@ -396,7 +431,7 @@ void pcps_acquisition::send_negative_acquisition() void pcps_acquisition::dump_results(int32_t effective_fft_size) { d_dump_number++; - std::string filename = acq_parameters.dump_filename; + std::string filename = d_dump_filename; filename.append("_"); filename.append(1, d_gnss_synchro->System); filename.append("_"); @@ -414,7 +449,7 @@ void pcps_acquisition::dump_results(int32_t effective_fft_size) if (matfp == NULL) { std::cout << "Unable to create or open Acquisition dump file" << std::endl; - acq_parameters.dump = false; + //acq_parameters.dump = false; } else { @@ -669,7 +704,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) volk_32f_x2_add_32f(d_magnitude_grid[doppler_index], d_magnitude_grid[doppler_index], d_tmp_buffer, effective_fft_size); } // Record results to file if required - if (acq_parameters.dump and d_channel == d_dump_channel) + if (d_dump and d_channel == d_dump_channel) { memcpy(grid_.colptr(doppler_index), d_magnitude_grid[doppler_index], sizeof(float) * effective_fft_size); } @@ -716,7 +751,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) volk_32f_x2_add_32f(d_magnitude_grid[doppler_index], d_magnitude_grid[doppler_index], d_tmp_buffer, effective_fft_size); } // Record results to file if required - if (acq_parameters.dump and d_channel == d_dump_channel) + if (d_dump and d_channel == d_dump_channel) { memcpy(narrow_grid_.colptr(doppler_index), d_magnitude_grid[doppler_index], sizeof(float) * effective_fft_size); } @@ -816,7 +851,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) if ((d_num_noncoherent_integrations_counter == acq_parameters.max_dwells) or (d_positive_acq == 1)) { // Record results to file if required - if (acq_parameters.dump and d_channel == d_dump_channel) + if (d_dump and d_channel == d_dump_channel) { pcps_acquisition::dump_results(effective_fft_size); } diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index c97daef96..4e46d049b 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -138,6 +138,8 @@ private: int64_t d_dump_number; uint32_t d_dump_channel; uint32_t d_buffer_count; + bool d_dump; + std::string d_dump_filename; public: ~pcps_acquisition(); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.cc index a056436a5..894b6ef20 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.cc @@ -34,6 +34,8 @@ #include "gps_sdr_signal_processing.h" #include "control_message_factory.h" #include "GPS_L1_CA.h" +#include "gnss_sdr_create_directory.h" +#include #include #include #include @@ -85,6 +87,38 @@ pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(const Acq_Con d_dump = conf_.dump; d_dump_filename = conf_.dump_filename; + if (d_dump) + { + std::string dump_path; + // Get path + if (d_dump_filename.find_last_of("/") != std::string::npos) + { + 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 = "acquisition"; + } + // 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 + boost::filesystem::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 Acquisition block. Wrong permissions?" << std::endl; + d_dump = false; + } + } + d_n_samples_in_buffer = 0; d_threshold = 0; d_num_doppler_points = 0; diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc index c16f25422..8e4a3120d 100644 --- a/src/algorithms/channel/adapters/channel.cc +++ b/src/algorithms/channel/adapters/channel.cc @@ -196,6 +196,19 @@ void Channel::set_signal(const Gnss_Signal& gnss_signal) } +void Channel::stop_channel() +{ + std::lock_guard lk(mx); + bool result = channel_fsm_->Event_stop_channel(); + if (!result) + { + LOG(WARNING) << "Invalid channel event"; + return; + } + DLOG(INFO) + << "Channel stop_channel()"; +} + void Channel::start_acquisition() { std::lock_guard lk(mx); diff --git a/src/algorithms/channel/adapters/channel.h b/src/algorithms/channel/adapters/channel.h index 780ee1ec2..3802ff107 100644 --- a/src/algorithms/channel/adapters/channel.h +++ b/src/algorithms/channel/adapters/channel.h @@ -73,21 +73,17 @@ public: gr::basic_block_sptr get_right_block() override; inline std::string role() override { return role_; } - //! Returns "Channel" inline std::string implementation() override { return implementation_; } - inline size_t item_size() override { return 0; } - inline Gnss_Signal get_signal() const override { return gnss_signal_; } - void start_acquisition() override; //!< Start the State Machine + void stop_channel() override; //!< Stop the State Machine void set_signal(const Gnss_Signal& gnss_signal_) override; //!< Sets the channel GNSS signal inline std::shared_ptr acquisition() { return acq_; } inline std::shared_ptr tracking() { return trk_; } inline std::shared_ptr telemetry() { return nav_; } - void msg_handler_events(pmt::pmt_t msg); private: diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index 4296ccf0d..5b212193a 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -52,6 +52,28 @@ ChannelFsm::ChannelFsm(std::shared_ptr acquisition) : acq_ } +bool ChannelFsm::Event_stop_channel() +{ + std::lock_guard lk(mx); + DLOG(INFO) << "CH = " << channel_ << ". Ev stop channel"; + switch (d_state) + { + case 0: //already in stanby + return true; + break; + case 1: //acquisition + d_state = 0; + stop_acquisition(); + break; + case 2: //tracking + d_state = 0; + stop_tracking(); + break; + default: + return true; + } +} + bool ChannelFsm::Event_start_acquisition() { std::lock_guard lk(mx); @@ -165,6 +187,17 @@ void ChannelFsm::set_channel(uint32_t channel) } +void ChannelFsm::stop_acquisition() +{ + acq_->stop_acquisition(); +} + +void ChannelFsm::stop_tracking() +{ + trk_->stop_tracking(); +} + + void ChannelFsm::start_acquisition() { acq_->reset(); diff --git a/src/algorithms/channel/libs/channel_fsm.h b/src/algorithms/channel/libs/channel_fsm.h index d1fe8e1bf..c2ee6c728 100644 --- a/src/algorithms/channel/libs/channel_fsm.h +++ b/src/algorithms/channel/libs/channel_fsm.h @@ -58,6 +58,7 @@ public: //FSM EVENTS bool Event_start_acquisition(); bool Event_valid_acquisition(); + bool Event_stop_channel(); bool Event_failed_acquisition_repeat(); bool Event_failed_acquisition_no_repeat(); bool Event_failed_tracking_standby(); @@ -65,6 +66,8 @@ public: private: void start_acquisition(); void start_tracking(); + void stop_acquisition(); + void stop_tracking(); void request_satellite(); void notify_stop_tracking(); diff --git a/src/algorithms/libs/CMakeLists.txt b/src/algorithms/libs/CMakeLists.txt index ab7af677e..18dd400b0 100644 --- a/src/algorithms/libs/CMakeLists.txt +++ b/src/algorithms/libs/CMakeLists.txt @@ -38,6 +38,7 @@ set(GNSS_SPLIBS_SOURCES conjugate_cc.cc conjugate_sc.cc conjugate_ic.cc + gnss_sdr_create_directory.cc ) set(GNSS_SPLIBS_HEADERS @@ -60,6 +61,7 @@ set(GNSS_SPLIBS_HEADERS conjugate_cc.h conjugate_sc.h conjugate_ic.h + gnss_sdr_create_directory.h gnss_circular_deque.h ) @@ -74,7 +76,7 @@ if(ENABLE_FPGA) gnss_sdr_time_counter.h gnss_sdr_fpga_sample_counter.h ) - + endif(ENABLE_FPGA) if(OPENCL_FOUND) @@ -83,12 +85,12 @@ if(OPENCL_FOUND) opencl/fft_setup.cc # Needs OpenCL opencl/fft_kernelstring.cc # Needs OpenCL ) - + set(GNSS_SPLIBS_HEADERS ${GNSS_SPLIBS_HEADERS} opencl/fft_execute.h # Needs OpenCL opencl/fft_setup.h # Needs OpenCL opencl/fft_kernelstring.h # Needs OpenCL - ) + ) endif(OPENCL_FOUND) include_directories( diff --git a/src/algorithms/libs/gnss_sdr_create_directory.cc b/src/algorithms/libs/gnss_sdr_create_directory.cc new file mode 100644 index 000000000..3a880143b --- /dev/null +++ b/src/algorithms/libs/gnss_sdr_create_directory.cc @@ -0,0 +1,87 @@ +/*! + * \file gnss_sdr_create_directory.cc + * \brief Create a directory + * \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#include "gnss_sdr_create_directory.h" +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem +#include + + +bool gnss_sdr_create_directory(const std::string& foldername) +{ + std::string new_folder; + for (auto& folder : boost::filesystem::path(foldername)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + try + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + return false; + } + } + catch (std::exception& e) + { + return false; + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + + // Check if we have writing permissions + std::string test_file = foldername + "/test_file.txt"; + std::ofstream os_test_file; + os_test_file.open(test_file.c_str(), std::ios::out | std::ios::binary); + + if (os_test_file.is_open()) + { + boost::system::error_code ec; + os_test_file.close(); + try + { + boost::filesystem::remove(test_file, ec); + } + catch (std::exception& e) + { + return false; + } + return true; + } + else + { + os_test_file.close(); + return false; + } +} diff --git a/src/algorithms/libs/gnss_sdr_create_directory.h b/src/algorithms/libs/gnss_sdr_create_directory.h new file mode 100644 index 000000000..23de7ec14 --- /dev/null +++ b/src/algorithms/libs/gnss_sdr_create_directory.h @@ -0,0 +1,38 @@ +/*! + * \file gnss_sdr_create_directory.h + * \brief Create a directory + * \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GNSS_SDR_CREATE_DIRECTORY_H_ +#define GNSS_SDR_GNSS_SDR_CREATE_DIRECTORY_H_ + +#include + +bool gnss_sdr_create_directory(const std::string& foldername); + +#endif diff --git a/src/algorithms/libs/rtklib/rtklib_pntpos.cc b/src/algorithms/libs/rtklib/rtklib_pntpos.cc index 13a94502a..6473b98a0 100644 --- a/src/algorithms/libs/rtklib/rtklib_pntpos.cc +++ b/src/algorithms/libs/rtklib/rtklib_pntpos.cc @@ -739,6 +739,7 @@ int resdop(const obsd_t *obs, int n, const double *rs, const double *dts, { double lam, rate, pos[3], E[9], a[3], e[3], vs[3], cosel; int i, j, nv = 0; + int band = 0; trace(3, "resdop : n=%d\n", n); @@ -747,9 +748,12 @@ int resdop(const obsd_t *obs, int n, const double *rs, const double *dts, for (i = 0; i < n && i < MAXOBS; i++) { - lam = nav->lam[obs[i].sat - 1][0]; + if (obs[i].code[0] != CODE_NONE) band = 0; + if (obs[i].code[1] != CODE_NONE) band = 1; + if (obs[i].code[2] != CODE_NONE) band = 2; + lam = nav->lam[obs[i].sat - 1][band]; - if (obs[i].D[0] == 0.0 || lam == 0.0 || !vsat[i] || norm_rtk(rs + 3 + i * 6, 3) <= 0.0) + if (obs[i].D[band] == 0.0 || lam == 0.0 || !vsat[i] || norm_rtk(rs + 3 + i * 6, 3) <= 0.0) { continue; } @@ -767,7 +771,7 @@ int resdop(const obsd_t *obs, int n, const double *rs, const double *dts, rate = dot(vs, e, 3) + DEFAULT_OMEGA_EARTH_DOT / SPEED_OF_LIGHT * (rs[4 + i * 6] * rr[0] + rs[1 + i * 6] * x[0] - rs[3 + i * 6] * rr[1] - rs[i * 6] * x[1]); /* doppler residual */ - v[nv] = -lam * obs[i].D[0] - (rate + x[3] - SPEED_OF_LIGHT * dts[1 + i * 2]); + v[nv] = -lam * obs[i].D[band] - (rate + x[3] - SPEED_OF_LIGHT * dts[1 + i * 2]); /* design matrix */ for (j = 0; j < 4; j++) H[j + nv * 4] = j < 3 ? -e[j] : 1.0; diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/cmake_uninstall.cmake.in b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/cmake_uninstall.cmake.in index a6191a104..d026a667a 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/cmake_uninstall.cmake.in +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/cmake_uninstall.cmake.in @@ -25,10 +25,10 @@ string(REGEX REPLACE "\n" ";" files "${files}") foreach(file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") - exec_program( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + execute_process( + COMMAND @CMAKE_COMMAND@ -E remove \"$ENV{DESTDIR}${file}\" OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval + RESULT_VARIABLE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") diff --git a/src/algorithms/observables/adapters/hybrid_observables.cc b/src/algorithms/observables/adapters/hybrid_observables.cc index 4313edfee..cf03f2d2c 100644 --- a/src/algorithms/observables/adapters/hybrid_observables.cc +++ b/src/algorithms/observables/adapters/hybrid_observables.cc @@ -38,21 +38,22 @@ using google::LogMessage; HybridObservables::HybridObservables(ConfigurationInterface* configuration, - std::string role, unsigned int in_streams, unsigned int out_streams) : - role_(role), in_streams_(in_streams), out_streams_(out_streams) + std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { std::string default_dump_filename = "./observables.dat"; DLOG(INFO) << "role " << role; dump_ = configuration->property(role + ".dump", false); + dump_mat_ = configuration->property(role + ".dump_mat", true); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); - observables_ = hybrid_make_observables_cc(in_streams_, out_streams_, dump_, dump_filename_); + observables_ = hybrid_make_observables_cc(in_streams_, out_streams_, dump_, dump_mat_, dump_filename_); DLOG(INFO) << "Observables block ID (" << observables_->unique_id() << ")"; } HybridObservables::~HybridObservables() -{} +{ +} void HybridObservables::connect(gr::top_block_sptr top_block) diff --git a/src/algorithms/observables/adapters/hybrid_observables.h b/src/algorithms/observables/adapters/hybrid_observables.h index 57883374a..1beb968fa 100644 --- a/src/algorithms/observables/adapters/hybrid_observables.h +++ b/src/algorithms/observables/adapters/hybrid_observables.h @@ -83,6 +83,7 @@ public: private: hybrid_observables_cc_sptr observables_; bool dump_; + bool dump_mat_; std::string dump_filename_; std::string role_; unsigned int in_streams_; diff --git a/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt b/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt index d42409de6..82c5bc243 100644 --- a/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt @@ -16,11 +16,11 @@ # along with GNSS-SDR. If not, see . # -set(OBS_GR_BLOCKS_SOURCES +set(OBS_GR_BLOCKS_SOURCES hybrid_observables_cc.cc ) -set(OBS_GR_BLOCKS_HEADERS +set(OBS_GR_BLOCKS_HEADERS hybrid_observables_cc.h ) diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc index 81d385cf5..ffd395462 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -32,6 +32,8 @@ #include "hybrid_observables_cc.h" #include "display.h" #include "GPS_L1_CA.h" +#include "gnss_sdr_create_directory.h" +#include #include #include #include @@ -45,42 +47,70 @@ using google::LogMessage; -hybrid_observables_cc_sptr hybrid_make_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, std::string dump_filename) +hybrid_observables_cc_sptr hybrid_make_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, bool dump_mat, std::string dump_filename) { - return hybrid_observables_cc_sptr(new hybrid_observables_cc(nchannels_in, nchannels_out, dump, dump_filename)); + return hybrid_observables_cc_sptr(new hybrid_observables_cc(nchannels_in, nchannels_out, dump, dump_mat, dump_filename)); } hybrid_observables_cc::hybrid_observables_cc(uint32_t nchannels_in, uint32_t nchannels_out, bool dump, + bool dump_mat, std::string dump_filename) : gr::block("hybrid_observables_cc", gr::io_signature::make(nchannels_in, nchannels_in, sizeof(Gnss_Synchro)), gr::io_signature::make(nchannels_out, nchannels_out, sizeof(Gnss_Synchro))) { d_dump = dump; + d_dump_mat = dump_mat and d_dump; + d_dump_filename = dump_filename; d_nchannels_out = nchannels_out; d_nchannels_in = nchannels_in; - d_dump_filename = dump_filename; T_rx_clock_step_samples = 0U; d_gnss_synchro_history = new Gnss_circular_deque(500, d_nchannels_out); // ############# ENABLE DATA FILE LOG ################# if (d_dump) { - if (!d_dump_file.is_open()) + std::string dump_path; + // Get path + if (d_dump_filename.find_last_of("/") != std::string::npos) { - try - { - d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str(); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "Exception opening observables dump file " << e.what(); - d_dump = false; - } + 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 = "observables.dat"; + } + // 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.append(".dat"); + d_dump_filename = dump_path + boost::filesystem::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 Observables block. Wrong permissions?" << std::endl; + d_dump = false; + } + d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "Exception opening observables dump file " << e.what(); + d_dump = false; } } T_rx_TOW_ms = 0U; @@ -107,11 +137,9 @@ hybrid_observables_cc::~hybrid_observables_cc() LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); } } - if (d_dump) + if (d_dump_mat) { - std::cout << "Writing observables .mat files ..."; save_matfile(); - std::cout << " done." << std::endl; } } @@ -119,14 +147,16 @@ hybrid_observables_cc::~hybrid_observables_cc() int32_t hybrid_observables_cc::save_matfile() { // READ DUMP FILE + std::string dump_filename = d_dump_filename; std::ifstream::pos_type size; int32_t number_of_double_vars = 7; int32_t epoch_size_bytes = sizeof(double) * number_of_double_vars * d_nchannels_out; std::ifstream dump_file; + std::cout << "Generating .mat file for " << dump_filename << std::endl; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { - dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + dump_file.open(dump_filename.c_str(), std::ios::binary | std::ios::ate); } catch (const std::ifstream::failure &e) { @@ -553,7 +583,6 @@ int hybrid_observables_cc::general_work(int noutput_items __attribute__((unused) { out[n][0] = epoch_data.at(n); } - if (d_dump) { // MULTIPLEXED FILE RECORDING - Record results to file diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h index 0eed5da1b..033da7a25 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h @@ -48,7 +48,7 @@ class hybrid_observables_cc; typedef boost::shared_ptr hybrid_observables_cc_sptr; hybrid_observables_cc_sptr -hybrid_make_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, std::string dump_filename); +hybrid_make_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, bool dump_mat, std::string dump_filename); /*! * \brief This class implements a block that computes observables @@ -63,8 +63,8 @@ public: private: friend hybrid_observables_cc_sptr - hybrid_make_observables_cc(uint32_t nchannels_in, uint32_t nchannels_out, bool dump, std::string dump_filename); - hybrid_observables_cc(uint32_t nchannels_in, uint32_t nchannels_out, bool dump, std::string dump_filename); + hybrid_make_observables_cc(uint32_t nchannels_in, uint32_t nchannels_out, bool dump, bool dump_mat, std::string dump_filename); + hybrid_observables_cc(uint32_t nchannels_in, uint32_t nchannels_out, bool dump, bool dump_mat, std::string dump_filename); bool interpolate_data(Gnss_Synchro& out, const uint32_t& ch, const double& ti); bool interp_trk_obs(Gnss_Synchro& interpolated_obs, const uint32_t& ch, const uint64_t& rx_clock); double compute_T_rx_s(const Gnss_Synchro& a); @@ -82,6 +82,7 @@ private: uint32_t T_rx_TOW_ms; uint32_t T_rx_TOW_offset_ms; bool d_dump; + bool d_dump_mat; uint32_t d_nchannels_in; uint32_t d_nchannels_out; std::string d_dump_filename; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.cc index 2648788c9..da1851fad 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.cc @@ -335,23 +335,18 @@ void galileo_telemetry_decoder_cc::decode_INAV_word(double *page_part_symbols, i std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_utc_model()); std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << std::endl; this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + delta_t = tmp_obj->A_0G_10 + tmp_obj->A_1G_10 * (static_cast(d_TOW_at_current_symbol_ms) / 1000.0 - tmp_obj->t_0G_10 + 604800 * (fmod((d_inav_nav.WN_0 - tmp_obj->WN_0G_10), 64))); + DLOG(INFO) << "delta_t=" << delta_t << "[s]"; } if (d_inav_nav.have_new_almanac() == true) { - std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_almanac()); + std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_almanac()); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); //debug std::cout << "Galileo E1 I/NAV almanac received in channel " << d_channel << " from satellite " << d_satellite << std::endl; - DLOG(INFO) << "GPS_to_Galileo time conversion:"; - DLOG(INFO) << "A0G=" << tmp_obj->A_0G_10; - DLOG(INFO) << "A1G=" << tmp_obj->A_1G_10; - DLOG(INFO) << "T0G=" << tmp_obj->t_0G_10; - DLOG(INFO) << "WN_0G_10=" << tmp_obj->WN_0G_10; DLOG(INFO) << "Current parameters:"; DLOG(INFO) << "d_TOW_at_current_symbol_ms=" << d_TOW_at_current_symbol_ms; DLOG(INFO) << "d_nav.WN_0=" << d_inav_nav.WN_0; - delta_t = tmp_obj->A_0G_10 + tmp_obj->A_1G_10 * (static_cast(d_TOW_at_current_symbol_ms) / 1000.0 - tmp_obj->t_0G_10 + 604800 * (fmod((d_inav_nav.WN_0 - tmp_obj->WN_0G_10), 64))); - DLOG(INFO) << "delta_t=" << delta_t << "[s]"; } } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.h index a009fe66a..6dc96f309 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.h @@ -38,7 +38,7 @@ #include "galileo_navigation_message.h" #include "galileo_fnav_message.h" #include "galileo_ephemeris.h" -#include "galileo_almanac.h" +#include "galileo_almanac_helper.h" #include "galileo_iono.h" #include "galileo_utc_model.h" #include "gnss_satellite.h" diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc index 8a57fd975..bb1ff89cd 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GalileoE1DllPllVemlTracking::stop_tracking() +{ +} + GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -59,6 +63,11 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( trk_param.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param.dump_mat = dump_mat; trk_param.high_dyn = configuration->property(role + ".high_dyn", false); if (configuration->property(role + ".smoother_length", 10) < 1) { @@ -105,9 +114,6 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( } trk_param.track_pilot = track_pilot; trk_param.extend_correlation_symbols = extend_correlation_symbols; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param.dump_filename = dump_filename; int vector_length = std::round(fs_in / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)); trk_param.vector_length = vector_length; trk_param.system = 'E'; diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.h b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.h index 7904b958d..f6193fde5 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.h +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.h @@ -92,6 +92,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: dll_pll_veml_tracking_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.cc b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.cc index 6a5955b2d..ad9da322c 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.cc @@ -46,12 +46,16 @@ using google::LogMessage; +void GalileoE1DllPllVemlTrackingFpga::stop_tracking() +{ +} + GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { //dllpllconf_t trk_param; - Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); + Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## std::string default_item_type = "gr_complex"; @@ -61,6 +65,11 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga( trk_param_fpga.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param_fpga.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param_fpga.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param_fpga.dump_mat = dump_mat; float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 5.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param_fpga.pll_bw_hz = pll_bw_hz; @@ -98,9 +107,6 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga( trk_param_fpga.track_pilot = track_pilot; d_track_pilot = track_pilot; trk_param_fpga.extend_correlation_symbols = extend_correlation_symbols; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param_fpga.dump_filename = dump_filename; int vector_length = std::round(fs_in / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)); trk_param_fpga.vector_length = vector_length; trk_param_fpga.system = 'E'; @@ -126,23 +132,23 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga( unsigned int device_base = configuration->property(role + ".device_base", 15); trk_param_fpga.device_base = device_base; //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 1); - trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> 5 correlators + trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> 5 correlators //################# PRE-COMPUTE ALL THE CODES ################# unsigned int code_samples_per_chip = 2; - d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* code_samples_per_chip * Galileo_E1_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); - float * ca_codes_f; - float * data_codes_f; + d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) * code_samples_per_chip * Galileo_E1_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); + float* ca_codes_f; + float* data_codes_f; if (trk_param_fpga.track_pilot) { - d_data_codes = static_cast(volk_gnsssdr_malloc((static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)) * code_samples_per_chip * Galileo_E1_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); + d_data_codes = static_cast(volk_gnsssdr_malloc((static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)) * code_samples_per_chip * Galileo_E1_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); } - ca_codes_f = static_cast(volk_gnsssdr_malloc(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* code_samples_per_chip * sizeof(float), volk_gnsssdr_get_alignment())); + ca_codes_f = static_cast(volk_gnsssdr_malloc(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) * code_samples_per_chip * sizeof(float), volk_gnsssdr_get_alignment())); if (trk_param_fpga.track_pilot) { - data_codes_f = static_cast(volk_gnsssdr_malloc((static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)) * code_samples_per_chip * sizeof(float), volk_gnsssdr_get_alignment())); + data_codes_f = static_cast(volk_gnsssdr_malloc((static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)) * code_samples_per_chip * sizeof(float), volk_gnsssdr_get_alignment())); } //printf("pppppppp trk_param_fpga.track_pilot = %d\n", trk_param_fpga.track_pilot); @@ -159,12 +165,11 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga( galileo_e1_code_gen_sinboc11_float(ca_codes_f, pilot_signal, PRN); galileo_e1_code_gen_sinboc11_float(data_codes_f, data_signal, PRN); - for (unsigned int s = 0; s < 2*Galileo_E1_B_CODE_LENGTH_CHIPS; s++) + for (unsigned int s = 0; s < 2 * Galileo_E1_B_CODE_LENGTH_CHIPS; s++) { - d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s] = static_cast(ca_codes_f[s]); - d_data_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s] = static_cast(data_codes_f[s]); + d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) * 2 * (PRN - 1) + s] = static_cast(ca_codes_f[s]); + d_data_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) * 2 * (PRN - 1) + s] = static_cast(data_codes_f[s]); //printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); - } //printf("\n next \n"); //scanf ("%d",&kk); @@ -174,15 +179,14 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga( //printf("no tracking pilot\n"); galileo_e1_code_gen_sinboc11_float(ca_codes_f, data_signal, PRN); - for (unsigned int s = 0; s < 2*Galileo_E1_B_CODE_LENGTH_CHIPS; s++) + for (unsigned int s = 0; s < 2 * Galileo_E1_B_CODE_LENGTH_CHIPS; s++) { - d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s] = static_cast(ca_codes_f[s]); + d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) * 2 * (PRN - 1) + s] = static_cast(ca_codes_f[s]); //printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); } //printf("\n next \n"); //scanf ("%d",&kk); } - } delete[] ca_codes_f; @@ -193,7 +197,7 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga( trk_param_fpga.ca_codes = d_ca_codes; trk_param_fpga.data_codes = d_data_codes; trk_param_fpga.code_length_chips = Galileo_E1_B_CODE_LENGTH_CHIPS; - trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip + trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip //################# MAKE TRACKING GNURadio object ################### tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); channel_ = 0; @@ -207,7 +211,6 @@ GalileoE1DllPllVemlTrackingFpga::~GalileoE1DllPllVemlTrackingFpga() if (d_track_pilot) { delete[] d_data_codes; - } } diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h index 794e5596c..55d8127ee 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h @@ -93,6 +93,12 @@ public: void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + + private: //dll_pll_veml_tracking_sptr tracking_; dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; @@ -104,7 +110,6 @@ private: int* d_ca_codes; int* d_data_codes; bool d_track_pilot; - }; diff --git a/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.cc b/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.cc index 51e526173..5b21f41ee 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.cc @@ -44,6 +44,10 @@ using google::LogMessage; +void GalileoE1TcpConnectorTracking::stop_tracking() +{ +} + GalileoE1TcpConnectorTracking::GalileoE1TcpConnectorTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.h b/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.h index ae4b38220..8a75834d6 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.h +++ b/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.h @@ -93,6 +93,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: galileo_e1_tcp_connector_tracking_cc_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc index 00b37d7c1..c3a8244e2 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GalileoE5aDllPllTracking::stop_tracking() +{ +} + GalileoE5aDllPllTracking::GalileoE5aDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -59,6 +63,11 @@ GalileoE5aDllPllTracking::GalileoE5aDllPllTracking( trk_param.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param.dump_mat = dump_mat; trk_param.high_dyn = configuration->property(role + ".high_dyn", false); if (configuration->property(role + ".smoother_length", 10) < 1) { @@ -81,9 +90,6 @@ GalileoE5aDllPllTracking::GalileoE5aDllPllTracking( trk_param.dll_bw_narrow_hz = dll_bw_narrow_hz; float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); trk_param.early_late_space_chips = early_late_space_chips; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param.dump_filename = dump_filename; int vector_length = std::round(fs_in / (Galileo_E5a_CODE_CHIP_RATE_HZ / Galileo_E5a_CODE_LENGTH_CHIPS)); trk_param.vector_length = vector_length; int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.h b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.h index 484754b23..c9444f503 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.h @@ -91,6 +91,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: dll_pll_veml_tracking_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc index 469885378..07215e147 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc @@ -46,14 +46,18 @@ using google::LogMessage; +void GalileoE5aDllPllTrackingFpga::stop_tracking() +{ +} + GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( - ConfigurationInterface* configuration, std::string role, + ConfigurationInterface *configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - //printf("creating the E5A tracking"); + //printf("creating the E5A tracking"); - Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); + Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## std::string default_item_type = "gr_complex"; @@ -63,6 +67,11 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( trk_param_fpga.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param_fpga.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param_fpga.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param_fpga.dump_mat = dump_mat; float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 20.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param_fpga.pll_bw_hz = pll_bw_hz; @@ -75,9 +84,6 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz; float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); trk_param_fpga.early_late_space_chips = early_late_space_chips; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param_fpga.dump_filename = dump_filename; int vector_length = std::round(fs_in / (Galileo_E5a_CODE_CHIP_RATE_HZ / Galileo_E5a_CODE_LENGTH_CHIPS)); trk_param_fpga.vector_length = vector_length; int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); @@ -126,7 +132,7 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( unsigned int device_base = configuration->property(role + ".device_base", 27); trk_param_fpga.device_base = device_base; //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 1); - trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> up to 5+1 correlators + trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> up to 5+1 correlators //################# PRE-COMPUTE ALL THE CODES ################# unsigned int code_samples_per_chip = 1; @@ -143,7 +149,7 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( } tracking_code = static_cast(volk_gnsssdr_malloc(code_samples_per_chip * code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); - d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(code_length_chips)* code_samples_per_chip * Galileo_E5a_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); + d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(code_length_chips) * code_samples_per_chip * Galileo_E5a_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); if (trk_param_fpga.track_pilot) { @@ -153,44 +159,36 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( for (unsigned int PRN = 1; PRN <= Galileo_E5a_NUMBER_OF_CODES; PRN++) { + //galileo_e5_a_code_gen_complex_primary(aux_code, PRN, const_cast(trk_param_fpga.signal.c_str())); + galileo_e5_a_code_gen_complex_primary(aux_code, PRN, const_cast(sig_)); + if (trk_param_fpga.track_pilot) + { + //d_secondary_code_string = const_cast(&Galileo_E5a_Q_SECONDARY_CODE[PRN - 1]); + for (unsigned int i = 0; i < code_length_chips; i++) + { + tracking_code[i] = aux_code[i].imag(); + data_code[i] = aux_code[i].real(); + } + for (unsigned int s = 0; s < code_length_chips; s++) + { + d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(tracking_code[s]); + d_data_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(data_code[s]); + //printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); + } + } + else + { + for (unsigned int i = 0; i < code_length_chips; i++) + { + tracking_code[i] = aux_code[i].real(); + } - - - //galileo_e5_a_code_gen_complex_primary(aux_code, PRN, const_cast(trk_param_fpga.signal.c_str())); - galileo_e5_a_code_gen_complex_primary(aux_code, PRN, const_cast(sig_)); - if (trk_param_fpga.track_pilot) - { - //d_secondary_code_string = const_cast(&Galileo_E5a_Q_SECONDARY_CODE[PRN - 1]); - for (unsigned int i = 0; i < code_length_chips; i++) - { - tracking_code[i] = aux_code[i].imag(); - data_code[i] = aux_code[i].real(); - } - for (unsigned int s = 0; s < code_length_chips; s++) - { - d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(tracking_code[s]); - d_data_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(data_code[s]); - //printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); - - } - - } - else - { - for (unsigned int i = 0; i < code_length_chips; i++) - { - tracking_code[i] = aux_code[i].real(); - } - - for (unsigned int s = 0; s < code_length_chips; s++) - { - d_ca_codes[static_cast(code_length_chips)* (PRN - 1) + s] = static_cast(tracking_code[s]); - //printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); - } - - } - - + for (unsigned int s = 0; s < code_length_chips; s++) + { + d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(tracking_code[s]); + //printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); + } + } } volk_gnsssdr_free(aux_code); @@ -202,25 +200,23 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( trk_param_fpga.ca_codes = d_ca_codes; trk_param_fpga.data_codes = d_data_codes; trk_param_fpga.code_length_chips = code_length_chips; - trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip + trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip //################# MAKE TRACKING GNURadio object ################### tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); -// if (item_type.compare("gr_complex") == 0) -// { -// item_size_ = sizeof(gr_complex); -// tracking_ = dll_pll_veml_make_tracking(trk_param_fpga); -// } -// else -// { -// item_size_ = sizeof(gr_complex); -// LOG(WARNING) << item_type << " unknown tracking item type."; -// } + // if (item_type.compare("gr_complex") == 0) + // { + // item_size_ = sizeof(gr_complex); + // tracking_ = dll_pll_veml_make_tracking(trk_param_fpga); + // } + // else + // { + // item_size_ = sizeof(gr_complex); + // LOG(WARNING) << item_type << " unknown tracking item type."; + // } channel_ = 0; //DLOG(INFO) << "tracking(" << tracking_->unique_id() << ")"; DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; - - } @@ -230,7 +226,6 @@ GalileoE5aDllPllTrackingFpga::~GalileoE5aDllPllTrackingFpga() if (d_track_pilot) { delete[] d_data_codes; - } } @@ -247,14 +242,14 @@ void GalileoE5aDllPllTrackingFpga::start_tracking() */ void GalileoE5aDllPllTrackingFpga::set_channel(unsigned int channel) { - //printf("blabla channel = %d\n", channel); + //printf("blabla channel = %d\n", channel); channel_ = channel; //tracking_->set_channel(channel); tracking_fpga_sc->set_channel(channel); } -void GalileoE5aDllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +void GalileoE5aDllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) { //tracking_->set_gnss_synchro(p_gnss_synchro); tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h index 8dce1b428..45325d458 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h @@ -91,6 +91,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; @@ -104,7 +108,6 @@ private: int* d_ca_codes; int* d_data_codes; bool d_track_pilot; - }; #endif /* GNSS_SDR_GALILEO_E5A_DLL_PLL_TRACKING_FPGA_H_ */ diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc index 16e212a9c..2287f53ba 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc @@ -46,6 +46,10 @@ using google::LogMessage; +void GlonassL1CaDllPllCAidTracking::stop_tracking() +{ +} + GlonassL1CaDllPllCAidTracking::GlonassL1CaDllPllCAidTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h index 3f75715dc..26e1f0db9 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h @@ -93,6 +93,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr tracking_cc; diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc index c616595d5..eb5f35176 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GlonassL1CaDllPllTracking::stop_tracking() +{ +} + GlonassL1CaDllPllTracking::GlonassL1CaDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.h b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.h index f752239d3..d5e1a4544 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.h @@ -91,6 +91,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: glonass_l1_ca_dll_pll_tracking_cc_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.cc b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.cc index be2bb41d3..d4d0d0e98 100644 --- a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.cc @@ -44,6 +44,10 @@ using google::LogMessage; +void GlonassL2CaDllPllCAidTracking::stop_tracking() +{ +} + GlonassL2CaDllPllCAidTracking::GlonassL2CaDllPllCAidTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.h b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.h index bdd377b75..085cf73ac 100644 --- a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.h +++ b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.h @@ -91,6 +91,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: glonass_l2_ca_dll_pll_c_aid_tracking_cc_sptr tracking_cc; diff --git a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.cc index 6d9a9f1ea..a6a49aa1c 100644 --- a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.cc @@ -43,6 +43,10 @@ using google::LogMessage; +void GlonassL2CaDllPllTracking::stop_tracking() +{ +} + GlonassL2CaDllPllTracking::GlonassL2CaDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.h b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.h index 66346bd71..1c2b715ed 100644 --- a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.h @@ -90,6 +90,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: glonass_l2_ca_dll_pll_tracking_cc_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.cc index 9ce706ef3..c821d311d 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GpsL1CaDllPllCAidTracking::stop_tracking() +{ +} + GpsL1CaDllPllCAidTracking::GpsL1CaDllPllCAidTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.h index 357a5a0c1..6b4dec2e5 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.h @@ -92,6 +92,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: gps_l1_ca_dll_pll_c_aid_tracking_cc_sptr tracking_cc; diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc index b9a8b2c6e..b0fff7263 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc @@ -45,6 +45,11 @@ using google::LogMessage; +void GpsL1CaDllPllTracking::stop_tracking() +{ + tracking_->stop_tracking(); +} + GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -69,6 +74,11 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( } bool dump = configuration->property(role + ".dump", false); trk_param.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param.dump_mat = dump_mat; float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param.pll_bw_hz = pll_bw_hz; @@ -83,9 +93,6 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( trk_param.early_late_space_chips = early_late_space_chips; float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.5); trk_param.early_late_space_narrow_chips = early_late_space_narrow_chips; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param.dump_filename = dump_filename; int vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); trk_param.vector_length = vector_length; int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1); diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.h index b85147b58..cbd4797f2 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.h @@ -91,6 +91,11 @@ public: void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + private: dll_pll_veml_tracking_sptr tracking_; size_t item_size_; diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc index 2e7125d5d..571d89c6b 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc @@ -48,14 +48,17 @@ using google::LogMessage; -GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga( - ConfigurationInterface* configuration, std::string role, - unsigned int in_streams, unsigned int out_streams) : - role_(role), in_streams_(in_streams), out_streams_(out_streams) +void GpsL1CaDllPllTrackingFpga::stop_tracking() { - Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); +} + +GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga( + ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); DLOG(INFO) << "role " << role; - + //################# CONFIGURATION PARAMETERS ######################## //std::string default_item_type = "gr_complex"; //std::string item_type = configuration->property(role + ".item_type", default_item_type); @@ -64,6 +67,11 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga( trk_param_fpga.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param_fpga.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param_fpga.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param_fpga.dump_mat = dump_mat; float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param_fpga.pll_bw_hz = pll_bw_hz; @@ -78,9 +86,6 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga( trk_param_fpga.early_late_space_chips = early_late_space_chips; float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.5); trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param_fpga.dump_filename = dump_filename; int vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); trk_param_fpga.vector_length = vector_length; int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1); @@ -130,23 +135,22 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga( unsigned int device_base = configuration->property(role + ".device_base", 3); trk_param_fpga.device_base = device_base; //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 0); - trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators + trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators //################# PRE-COMPUTE ALL THE CODES ################# - d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS*NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); + d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS * NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) - { - gps_l1_ca_code_gen_int(&d_ca_codes[(int(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0); - } + { + gps_l1_ca_code_gen_int(&d_ca_codes[(int(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0); + } trk_param_fpga.ca_codes = d_ca_codes; trk_param_fpga.code_length_chips = GPS_L1_CA_CODE_LENGTH_CHIPS; - trk_param_fpga.code_samples_per_chip = 1; // 1 sample per chip + trk_param_fpga.code_samples_per_chip = 1; // 1 sample per chip //################# MAKE TRACKING GNURadio object ################### tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); channel_ = 0; DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; - } GpsL1CaDllPllTrackingFpga::~GpsL1CaDllPllTrackingFpga() @@ -175,14 +179,18 @@ void GpsL1CaDllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) void GpsL1CaDllPllTrackingFpga::connect(gr::top_block_sptr top_block) { - if(top_block) { /* top_block is not null */}; + if (top_block) + { /* top_block is not null */ + }; //nothing to connect } void GpsL1CaDllPllTrackingFpga::disconnect(gr::top_block_sptr top_block) { - if(top_block) { /* top_block is not null */}; + if (top_block) + { /* top_block is not null */ + }; //nothing to disconnect } @@ -197,5 +205,3 @@ gr::basic_block_sptr GpsL1CaDllPllTrackingFpga::get_right_block() { return tracking_fpga_sc; } - - diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h index ea9c98423..80b998246 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h @@ -53,9 +53,9 @@ class GpsL1CaDllPllTrackingFpga : public TrackingInterface { public: GpsL1CaDllPllTrackingFpga(ConfigurationInterface* configuration, - std::string role, - unsigned int in_streams, - unsigned int out_streams); + std::string role, + unsigned int in_streams, + unsigned int out_streams); virtual ~GpsL1CaDllPllTrackingFpga(); @@ -93,10 +93,13 @@ public: void start_tracking() override; - //void reset(void); - + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + private: - dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; + dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; size_t item_size_; unsigned int channel_; std::string role_; @@ -105,4 +108,4 @@ private: int* d_ca_codes; }; -#endif // GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_H_ +#endif // GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_H_ diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.cc index 0cccd8e26..c82f228b5 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.cc @@ -44,6 +44,10 @@ using google::LogMessage; +void GpsL1CaDllPllTrackingGPU::stop_tracking() +{ +} + GpsL1CaDllPllTrackingGPU::GpsL1CaDllPllTrackingGPU( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.h index 9c77f4743..794152bb8 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.h @@ -91,6 +91,11 @@ public: void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + private: gps_l1_ca_dll_pll_tracking_gpu_cc_sptr tracking_; size_t item_size_; diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.cc index 38b3e3cad..2c33723e6 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.cc @@ -47,6 +47,10 @@ using google::LogMessage; +void GpsL1CaKfTracking::stop_tracking() +{ +} + GpsL1CaKfTracking::GpsL1CaKfTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.h b/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.h index e17831ffb..d8af76ce8 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.h @@ -93,6 +93,11 @@ public: void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + private: gps_l1_ca_kf_tracking_cc_sptr tracking_; size_t item_size_; diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.cc index d0303867c..9e3cf4bfa 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.cc @@ -43,6 +43,10 @@ using google::LogMessage; +void GpsL1CaTcpConnectorTracking::stop_tracking() +{ +} + GpsL1CaTcpConnectorTracking::GpsL1CaTcpConnectorTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.h b/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.h index 75a986cfc..f2fb94b3a 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.h @@ -91,6 +91,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: gps_l1_ca_tcp_connector_tracking_cc_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc index 499427dfa..f4bb44321 100644 --- a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GpsL2MDllPllTracking::stop_tracking() +{ +} + GpsL2MDllPllTracking::GpsL2MDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -59,6 +63,11 @@ GpsL2MDllPllTracking::GpsL2MDllPllTracking( trk_param.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param.dump_mat = dump_mat; float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 2.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param.pll_bw_hz = pll_bw_hz; @@ -68,9 +77,6 @@ GpsL2MDllPllTracking::GpsL2MDllPllTracking( float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); trk_param.early_late_space_chips = early_late_space_chips; trk_param.early_late_space_narrow_chips = 0.0; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param.dump_filename = dump_filename; int vector_length = std::round(static_cast(fs_in) / (static_cast(GPS_L2_M_CODE_RATE_HZ) / static_cast(GPS_L2_M_CODE_LENGTH_CHIPS))); trk_param.vector_length = vector_length; int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1); diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.h b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.h index 68305ad6a..23835c405 100644 --- a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.h @@ -90,6 +90,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: dll_pll_veml_tracking_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.cc index 5cdf87185..f10d876dc 100644 --- a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.cc @@ -47,12 +47,16 @@ using google::LogMessage; +void GpsL2MDllPllTrackingFpga::stop_tracking() +{ +} + GpsL2MDllPllTrackingFpga::GpsL2MDllPllTrackingFpga( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { //dllpllconf_t trk_param; - Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); + Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## //std::string default_item_type = "gr_complex"; @@ -62,6 +66,11 @@ GpsL2MDllPllTrackingFpga::GpsL2MDllPllTrackingFpga( trk_param_fpga.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param_fpga.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param_fpga.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param_fpga.dump_mat = dump_mat; float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 2.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param_fpga.pll_bw_hz = pll_bw_hz; @@ -71,9 +80,6 @@ GpsL2MDllPllTrackingFpga::GpsL2MDllPllTrackingFpga( float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); trk_param_fpga.early_late_space_chips = early_late_space_chips; trk_param_fpga.early_late_space_narrow_chips = 0.0; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param_fpga.dump_filename = dump_filename; int vector_length = std::round(static_cast(fs_in) / (static_cast(GPS_L2_M_CODE_RATE_HZ) / static_cast(GPS_L2_M_CODE_LENGTH_CHIPS))); trk_param_fpga.vector_length = vector_length; int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1); @@ -115,43 +121,43 @@ GpsL2MDllPllTrackingFpga::GpsL2MDllPllTrackingFpga( unsigned int device_base = configuration->property(role + ".device_base", 1); trk_param_fpga.device_base = device_base; //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 0); - trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators + trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators //d_tracking_code = static_cast(volk_gnsssdr_malloc(2 * static_cast(GPS_L2_M_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); - d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L2_M_CODE_LENGTH_CHIPS)* NUM_PRNs * sizeof(int), volk_gnsssdr_get_alignment())); - float* ca_codes_f = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L2_M_CODE_LENGTH_CHIPS)* sizeof(float), volk_gnsssdr_get_alignment())); + d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L2_M_CODE_LENGTH_CHIPS) * NUM_PRNs * sizeof(int), volk_gnsssdr_get_alignment())); + float* ca_codes_f = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L2_M_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); //################# PRE-COMPUTE ALL THE CODES ################# - d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L2_M_CODE_LENGTH_CHIPS*NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); + d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L2_M_CODE_LENGTH_CHIPS * NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) - { - //gps_l1_ca_code_gen_int(&d_ca_codes[(int(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0); - gps_l2c_m_code_gen_float(ca_codes_f, PRN); - for (unsigned int s = 0; s < 2*static_cast(GPS_L2_M_CODE_LENGTH_CHIPS); s++) - { - d_ca_codes[static_cast(GPS_L2_M_CODE_LENGTH_CHIPS)* (PRN - 1) + s] = static_cast(ca_codes_f[s]); - } - } + { + //gps_l1_ca_code_gen_int(&d_ca_codes[(int(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0); + gps_l2c_m_code_gen_float(ca_codes_f, PRN); + for (unsigned int s = 0; s < 2 * static_cast(GPS_L2_M_CODE_LENGTH_CHIPS); s++) + { + d_ca_codes[static_cast(GPS_L2_M_CODE_LENGTH_CHIPS) * (PRN - 1) + s] = static_cast(ca_codes_f[s]); + } + } delete[] ca_codes_f; trk_param_fpga.ca_codes = d_ca_codes; trk_param_fpga.code_length_chips = GPS_L2_M_CODE_LENGTH_CHIPS; - trk_param_fpga.code_samples_per_chip = 1; // 1 sample per chip + trk_param_fpga.code_samples_per_chip = 1; // 1 sample per chip //################# MAKE TRACKING GNURadio object ################### -// //################# MAKE TRACKING GNURadio object ################### -// if (item_type.compare("gr_complex") == 0) -// { -// item_size_ = sizeof(gr_complex); -// tracking_ = dll_pll_veml_make_tracking(trk_param); -// } -// else -// { -// item_size_ = sizeof(gr_complex); -// LOG(WARNING) << item_type << " unknown tracking item type."; -// } + // //################# MAKE TRACKING GNURadio object ################### + // if (item_type.compare("gr_complex") == 0) + // { + // item_size_ = sizeof(gr_complex); + // tracking_ = dll_pll_veml_make_tracking(trk_param); + // } + // else + // { + // item_size_ = sizeof(gr_complex); + // LOG(WARNING) << item_type << " unknown tracking item type."; + // } //################# MAKE TRACKING GNURadio object ################### tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h index d4dde0713..2cde19cd7 100644 --- a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h @@ -91,6 +91,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: //dll_pll_veml_tracking_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc index 1775a7a89..9954777ec 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GpsL5DllPllTracking::stop_tracking() +{ +} + GpsL5DllPllTracking::GpsL5DllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -59,6 +63,11 @@ GpsL5DllPllTracking::GpsL5DllPllTracking( trk_param.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param.dump_mat = dump_mat; trk_param.high_dyn = configuration->property(role + ".high_dyn", false); if (configuration->property(role + ".smoother_length", 10) < 1) { @@ -81,9 +90,6 @@ GpsL5DllPllTracking::GpsL5DllPllTracking( trk_param.dll_bw_narrow_hz = dll_bw_narrow_hz; float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); trk_param.early_late_space_chips = early_late_space_chips; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param.dump_filename = dump_filename; int vector_length = std::round(static_cast(fs_in) / (static_cast(GPS_L5i_CODE_RATE_HZ) / static_cast(GPS_L5i_CODE_LENGTH_CHIPS))); trk_param.vector_length = vector_length; int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.h b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.h index 9cfbd58fa..59a8983fc 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.h @@ -89,6 +89,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: dll_pll_veml_tracking_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc index 74e9f0566..bbf755f8e 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc @@ -47,13 +47,17 @@ using google::LogMessage; +void GpsL5DllPllTrackingFpga::stop_tracking() +{ +} + GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga( - ConfigurationInterface* configuration, std::string role, + ConfigurationInterface *configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - //printf("L5 TRK CLASS CREATED\n"); + //printf("L5 TRK CLASS CREATED\n"); //dllpllconf_t trk_param; - Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); + Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## //std::string default_item_type = "gr_complex"; @@ -63,6 +67,11 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga( trk_param_fpga.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param_fpga.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param_fpga.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param_fpga.dump_mat = dump_mat; float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param_fpga.pll_bw_hz = pll_bw_hz; @@ -75,9 +84,6 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga( trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz; float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); trk_param_fpga.early_late_space_chips = early_late_space_chips; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param_fpga.dump_filename = dump_filename; int vector_length = std::round(static_cast(fs_in) / (static_cast(GPS_L5i_CODE_RATE_HZ) / static_cast(GPS_L5i_CODE_LENGTH_CHIPS))); trk_param_fpga.vector_length = vector_length; int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); @@ -126,7 +132,7 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga( unsigned int device_base = configuration->property(role + ".device_base", 27); trk_param_fpga.device_base = device_base; //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 0); - trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators + trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators //################# PRE-COMPUTE ALL THE CODES ################# unsigned int code_samples_per_chip = 1; @@ -139,11 +145,11 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga( tracking_code = static_cast(volk_gnsssdr_malloc(code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); if (trk_param_fpga.track_pilot) - { - data_code = static_cast(volk_gnsssdr_malloc(code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); - } + { + data_code = static_cast(volk_gnsssdr_malloc(code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); + } - d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(code_length_chips*NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); + d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(code_length_chips * NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); if (trk_param_fpga.track_pilot) { @@ -152,35 +158,31 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga( //printf("start \n"); for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) - { - - if (track_pilot) - { - - gps_l5q_code_gen_float(tracking_code, PRN); - gps_l5i_code_gen_float(data_code, PRN); + { + if (track_pilot) + { + gps_l5q_code_gen_float(tracking_code, PRN); + gps_l5i_code_gen_float(data_code, PRN); - for (unsigned int s = 0; s < code_length_chips; s++) - { - d_ca_codes[static_cast(code_length_chips)* (PRN - 1) + s] = static_cast(tracking_code[s]); - d_data_codes[static_cast(code_length_chips)* (PRN - 1) + s] = static_cast(data_code[s]); - //printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); + for (unsigned int s = 0; s < code_length_chips; s++) + { + d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(tracking_code[s]); + d_data_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(data_code[s]); + //printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); + } + } - } - } - - else - { - - gps_l5i_code_gen_float(tracking_code, PRN); - for (unsigned int s = 0; s < code_length_chips; s++) - { - d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(data_code[s]); - //printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); - } - } - } + else + { + gps_l5i_code_gen_float(tracking_code, PRN); + for (unsigned int s = 0; s < code_length_chips; s++) + { + d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(data_code[s]); + //printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); + } + } + } //printf("end \n"); @@ -192,18 +194,18 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga( trk_param_fpga.ca_codes = d_ca_codes; trk_param_fpga.data_codes = d_data_codes; trk_param_fpga.code_length_chips = code_length_chips; - trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip + trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip //################# MAKE TRACKING GNURadio object ################### -// if (item_type.compare("gr_complex") == 0) -// { -// item_size_ = sizeof(gr_complex); -// tracking_ = dll_pll_veml_make_tracking(trk_param_fpga); -// } -// else -// { -// item_size_ = sizeof(gr_complex); -// LOG(WARNING) << item_type << " unknown tracking item type."; -// } + // if (item_type.compare("gr_complex") == 0) + // { + // item_size_ = sizeof(gr_complex); + // tracking_ = dll_pll_veml_make_tracking(trk_param_fpga); + // } + // else + // { + // item_size_ = sizeof(gr_complex); + // LOG(WARNING) << item_type << " unknown tracking item type."; + // } //printf("call \n"); tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); //printf("end2 \n"); @@ -214,19 +216,17 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga( GpsL5DllPllTrackingFpga::~GpsL5DllPllTrackingFpga() { - delete[] d_ca_codes; if (d_track_pilot) { delete[] d_data_codes; - } } void GpsL5DllPllTrackingFpga::start_tracking() { - tracking_fpga_sc->start_tracking(); + tracking_fpga_sc->start_tracking(); } @@ -240,9 +240,9 @@ void GpsL5DllPllTrackingFpga::set_channel(unsigned int channel) } -void GpsL5DllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +void GpsL5DllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) { - tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); + tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); } diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h index 6cb3bc170..64043fb70 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h @@ -89,6 +89,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: //dll_pll_veml_tracking_sptr tracking_; diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index a52ed894d..5401fae93 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -49,6 +49,7 @@ #include "gps_l2c_signal.h" #include "GPS_L5.h" #include "gps_l5_signal.h" +#include "gnss_sdr_create_directory.h" #include #include #include @@ -415,6 +416,42 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_carr_ph_history.resize(1); d_code_ph_history.resize(1); } + + d_dump = trk_parameters.dump; + d_dump_mat = trk_parameters.dump_mat and d_dump; + if (d_dump) + { + d_dump_filename = trk_parameters.dump_filename; + std::string dump_path; + // Get path + if (d_dump_filename.find_last_of("/") != std::string::npos) + { + 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 = "trk_channel_"; + } + // 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 + boost::filesystem::path::preferred_separator + d_dump_filename; + // create directory + if (!gnss_sdr_create_directory(dump_path)) + { + std::cerr << "GNSS-SDR cannot create dump files for the tracking block. Wrong permissions?" << std::endl; + d_dump = false; + } + } } @@ -592,17 +629,9 @@ dll_pll_veml_tracking::~dll_pll_veml_tracking() LOG(WARNING) << "Exception in destructor " << ex.what(); } } - if (trk_parameters.dump) + if (d_dump_mat) { - if (d_channel == 0) - { - std::cout << "Writing .mat files ..."; - } -// save_matfile(); - if (d_channel == 0) - { - std::cout << " done." << std::endl; - } + save_matfile(); } try { @@ -928,7 +957,7 @@ void dll_pll_veml_tracking::save_correlation_results() void dll_pll_veml_tracking::log_data(bool integrating) { - if (trk_parameters.dump) + if (d_dump) { // Dump results to file float prompt_I; @@ -1060,10 +1089,16 @@ int32_t dll_pll_veml_tracking::save_matfile() int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + sizeof(float) * number_of_float_vars + sizeof(uint32_t); std::ifstream dump_file; + std::string dump_filename_ = d_dump_filename; + // add channel number to the filename + dump_filename_.append(boost::lexical_cast(d_channel)); + // add extension + dump_filename_.append(".dat"); + std::cout << "Generating .mat file for " << dump_filename_ << std::endl; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { - dump_file.open(trk_parameters.dump_filename.c_str(), std::ios::binary | std::ios::ate); + dump_file.open(dump_filename_.c_str(), std::ios::binary | std::ios::ate); } catch (const std::ifstream::failure &e) { @@ -1168,7 +1203,7 @@ int32_t dll_pll_veml_tracking::save_matfile() // WRITE MAT FILE mat_t *matfp; matvar_t *matvar; - std::string filename = trk_parameters.dump_filename; + std::string filename = dump_filename_; filename.erase(filename.length() - 4, 4); filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); @@ -1296,17 +1331,23 @@ void dll_pll_veml_tracking::set_channel(uint32_t channel) d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; // ############# ENABLE DATA FILE LOG ################# - if (trk_parameters.dump) + if (d_dump) { + std::string dump_filename_ = d_dump_filename; + // add channel number to the filename + dump_filename_.append(boost::lexical_cast(d_channel)); + // add extension + dump_filename_.append(".dat"); + if (!d_dump_file.is_open()) { try { - trk_parameters.dump_filename.append(boost::lexical_cast(d_channel)); - trk_parameters.dump_filename.append(".dat"); + //trk_parameters.dump_filename.append(boost::lexical_cast(d_channel)); + //trk_parameters.dump_filename.append(".dat"); d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(trk_parameters.dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << trk_parameters.dump_filename.c_str(); + d_dump_file.open(dump_filename_.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << dump_filename_.c_str(); } catch (const std::ifstream::failure &e) { @@ -1324,6 +1365,12 @@ void dll_pll_veml_tracking::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) } +void dll_pll_veml_tracking::stop_tracking() +{ + gr::thread::scoped_lock l(d_setlock); + d_state = 0; +} + 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) { diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h index 226a540c8..37997bb84 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h @@ -61,6 +61,7 @@ public: void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro); void start_tracking(); + void stop_tracking(); int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); @@ -195,6 +196,9 @@ private: // file dump std::ofstream d_dump_file; + std::string d_dump_filename; + bool d_dump; + bool d_dump_mat; }; #endif // GNSS_SDR_DLL_PLL_VEML_TRACKING_H diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc index 90a3745d4..afd0d1b2d 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc @@ -47,6 +47,7 @@ #include "gps_l2c_signal.h" #include "GPS_L5.h" #include "gps_l5_signal.h" +#include "gnss_sdr_create_directory.h" #include #include #include @@ -420,6 +421,42 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & multicorrelator_fpga->set_output_vectors(d_correlator_outs, d_Prompt_Data); d_pull_in = 0; + + d_dump = trk_parameters.dump; + d_dump_mat = trk_parameters.dump_mat and d_dump; + if (d_dump) + { + d_dump_filename = trk_parameters.dump_filename; + std::string dump_path; + if (d_dump_filename.find_last_of("/") != std::string::npos) + { + 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 = "trk_channel_"; + } + // 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 + boost::filesystem::path::preferred_separator + d_dump_filename; + + // create directory + if (!gnss_sdr_create_directory(dump_path)) + { + std::cerr << "GNSS-SDR cannot create dump files for the tracking block. Wrong permissions?" << std::endl; + d_dump = false; + }; + } } @@ -587,17 +624,9 @@ dll_pll_veml_tracking_fpga::~dll_pll_veml_tracking_fpga() LOG(WARNING) << "Exception in destructor " << ex.what(); } } - if (trk_parameters.dump) + if (d_dump_mat) { - if (d_channel == 0) - { - std::cout << "Writing .mat files ..."; - } - // save_matfile(); - if (d_channel == 0) - { - std::cout << " done." << std::endl; - } + save_matfile(); } try { @@ -854,7 +883,7 @@ void dll_pll_veml_tracking_fpga::save_correlation_results() void dll_pll_veml_tracking_fpga::log_data(bool integrating) { - if (trk_parameters.dump) + if (d_dump) { // Dump results to file float prompt_I; @@ -980,10 +1009,16 @@ int32_t dll_pll_veml_tracking_fpga::save_matfile() int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + sizeof(float) * number_of_float_vars + sizeof(uint32_t); std::ifstream dump_file; + std::string dump_filename_ = d_dump_filename; + // add channel number to the filename + dump_filename_.append(boost::lexical_cast(d_channel)); + // add extension + dump_filename_.append(".dat"); + std::cout << "Generating .mat file for " << dump_filename_ << std::endl; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { - dump_file.open(trk_parameters.dump_filename.c_str(), std::ios::binary | std::ios::ate); + dump_file.open(dump_filename_.c_str(), std::ios::binary | std::ios::ate); } catch (const std::ifstream::failure &e) { @@ -1082,7 +1117,7 @@ int32_t dll_pll_veml_tracking_fpga::save_matfile() // WRITE MAT FILE mat_t *matfp; matvar_t *matvar; - std::string filename = trk_parameters.dump_filename; + std::string filename = dump_filename_; filename.erase(filename.length() - 4, 4); filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); @@ -1200,17 +1235,21 @@ void dll_pll_veml_tracking_fpga::set_channel(uint32_t channel) multicorrelator_fpga->set_channel(d_channel); LOG(INFO) << "Tracking Channel set to " << d_channel; // ############# ENABLE DATA FILE LOG ################# - if (trk_parameters.dump) + if (d_dump) { + std::string dump_filename_ = d_dump_filename; + // add channel number to the filename + dump_filename_.append(boost::lexical_cast(d_channel)); + // add extension + dump_filename_.append(".dat"); + if (!d_dump_file.is_open()) { try { - trk_parameters.dump_filename.append(boost::lexical_cast(d_channel)); - trk_parameters.dump_filename.append(".dat"); d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(trk_parameters.dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << trk_parameters.dump_filename.c_str(); + d_dump_file.open(dump_filename_.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << dump_filename_.c_str(); } catch (const std::ifstream::failure &e) { @@ -1226,11 +1265,15 @@ void dll_pll_veml_tracking_fpga::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) d_acquisition_gnss_synchro = p_gnss_synchro; } +void dll_pll_veml_tracking_fpga::stop_tracking() +{ + gr::thread::scoped_lock l(d_setlock); + d_state = 0; +} int dll_pll_veml_tracking_fpga::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) { - // Block input data and block output stream pointers Gnss_Synchro **out = reinterpret_cast(&output_items[0]); diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.h b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.h index 47090681b..91e34d400 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.h +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.h @@ -52,44 +52,11 @@ #include #include "fpga_multicorrelator.h" -//typedef struct -//{ -// /* DLL/PLL tracking configuration */ -// double fs_in; -// uint32_t vector_length; -// bool dump; -// std::string dump_filename; -// float pll_bw_hz; -// float dll_bw_hz; -// float pll_bw_narrow_hz; -// float dll_bw_narrow_hz; -// float early_late_space_chips; -// float very_early_late_space_chips; -// float early_late_space_narrow_chips; -// float very_early_late_space_narrow_chips; -// int32_t extend_correlation_symbols; -// int32_t cn0_samples; -// int32_t cn0_min; -// int32_t max_lock_fail; -// double carrier_lock_th; -// bool track_pilot; -// char system; -// char signal[3]; -// std::string device_name; -// uint32_t device_base; -// uint32_t multicorr_type; -// uint32_t code_length_chips; -// uint32_t code_samples_per_chip; -// int* ca_codes; -// int* data_codes; -//} dllpllconf_fpga_t; - class dll_pll_veml_tracking_fpga; typedef boost::shared_ptr dll_pll_veml_tracking_fpga_sptr; -//dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const dllpllconf_fpga_t &conf_); dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_); @@ -104,7 +71,7 @@ public: void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro); void start_tracking(); - + void stop_tracking(); int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); @@ -228,6 +195,9 @@ private: // file dump std::ofstream d_dump_file; + std::string d_dump_filename; + bool d_dump; + bool d_dump_mat; // extra int32_t d_correlation_length_samples; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc index 2415b4a43..2689e382f 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -1,5 +1,5 @@ /*! - * \file glonass_l1_ca_dll_pll_c_aid_tracking_cc.h + * \file glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc index fca20580e..19c5cca3e 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc @@ -1,5 +1,5 @@ /*! - * \file glonass_l2_ca_dll_pll_c_aid_tracking_cc.h + * \file glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc * \brief Implementation of a code DLL + carrier PLL tracking block * \author Damian Miralles, 2018. dmiralles2009(at)gmail.com * diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.h index da293dc47..7f714500e 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.h @@ -1,5 +1,5 @@ /*! - * \file gps_l1_ca_kf_tracking_cc.cc + * \file gps_l1_ca_kf_tracking_cc.h * \brief Interface of a processing block of a DLL + Kalman carrier * tracking loop for GPS L1 C/A signals * \author Javier Arribas, 2018. jarribas(at)cttc.es diff --git a/src/algorithms/tracking/libs/dll_pll_conf.cc b/src/algorithms/tracking/libs/dll_pll_conf.cc index c4b310c3d..77c0b48a3 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf.cc @@ -41,7 +41,8 @@ Dll_Pll_Conf::Dll_Pll_Conf() fs_in = 0.0; vector_length = 0U; dump = false; - dump_filename = "./dll_pll_dump.dat"; + dump_mat = true; + dump_filename = std::string("./dll_pll_dump.dat"); pll_pull_in_bw_hz = 50.0; dll_pull_in_bw_hz = 3.0; pll_bw_hz = 35.0; diff --git a/src/algorithms/tracking/libs/dll_pll_conf.h b/src/algorithms/tracking/libs/dll_pll_conf.h index 042ee46b6..0fbf07cc3 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.h +++ b/src/algorithms/tracking/libs/dll_pll_conf.h @@ -38,12 +38,12 @@ class Dll_Pll_Conf { -private: public: /* DLL/PLL tracking configuration */ double fs_in; uint32_t vector_length; bool dump; + bool dump_mat; std::string dump_filename; float pll_pull_in_bw_hz; float dll_pull_in_bw_hz; diff --git a/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc b/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc index 7f89ecaa9..87b66a911 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc @@ -35,35 +35,12 @@ Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga() { - // /* DLL/PLL tracking configuration */ - // fs_in = 0.0; - // vector_length = 0; - // dump = false; - // dump_filename = "./dll_pll_dump.dat"; - // pll_bw_hz = 40.0; - // dll_bw_hz = 2.0; - // pll_bw_narrow_hz = 5.0; - // dll_bw_narrow_hz = 0.75; - // early_late_space_chips = 0.5; - // very_early_late_space_chips = 0.5; - // early_late_space_narrow_chips = 0.1; - // very_early_late_space_narrow_chips = 0.1; - // extend_correlation_symbols = 5; - // cn0_samples = 20; - // carrier_lock_det_mav_samples = 20; - // cn0_min = 25; - // max_lock_fail = 50; - // carrier_lock_th = 0.85; - // track_pilot = false; - // system = 'G'; - // char sig_[3] = "1C"; - // std::memcpy(signal, sig_, 3); - /* DLL/PLL tracking configuration */ fs_in = 0.0; vector_length = 0U; dump = false; - dump_filename = "./dll_pll_dump.dat"; + dump_mat = true; + dump_filename = std::string("./dll_pll_dump.dat"); pll_bw_hz = 40.0; dll_bw_hz = 2.0; pll_bw_narrow_hz = 5.0; @@ -86,6 +63,6 @@ Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga() multicorr_type = 0U; code_length_chips = 0U; code_samples_per_chip = 0U; - //int32_t* ca_codes; - //int32_t* data_codes; + ca_codes = nullptr; + data_codes = nullptr; } diff --git a/src/algorithms/tracking/libs/dll_pll_conf_fpga.h b/src/algorithms/tracking/libs/dll_pll_conf_fpga.h index c00c1a2f2..8fd81fb36 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf_fpga.h +++ b/src/algorithms/tracking/libs/dll_pll_conf_fpga.h @@ -38,35 +38,12 @@ class Dll_Pll_Conf_Fpga { -private: public: - // /* DLL/PLL tracking configuration */ - // double fs_in; - // uint32_t vector_length; - // bool dump; - // std::string dump_filename; - // float pll_bw_hz; - // float dll_bw_hz; - // float pll_bw_narrow_hz; - // float dll_bw_narrow_hz; - // float early_late_space_chips; - // float very_early_late_space_chips; - // float early_late_space_narrow_chips; - // float very_early_late_space_narrow_chips; - // int32_t extend_correlation_symbols; - // int32_t cn0_samples; - // int32_t carrier_lock_det_mav_samples; - // int32_t cn0_min; - // int32_t max_lock_fail; - // double carrier_lock_th; - // bool track_pilot; - // char system; - // char signal[3]; - /* DLL/PLL tracking configuration */ double fs_in; uint32_t vector_length; bool dump; + bool dump_mat; std::string dump_filename; float pll_bw_hz; float dll_bw_hz; diff --git a/src/core/interfaces/acquisition_interface.h b/src/core/interfaces/acquisition_interface.h index dcf140a5f..d76e79bfc 100644 --- a/src/core/interfaces/acquisition_interface.h +++ b/src/core/interfaces/acquisition_interface.h @@ -64,6 +64,7 @@ public: virtual void set_state(int state) = 0; virtual signed int mag() = 0; virtual void reset() = 0; + virtual void stop_acquisition() = 0; }; #endif /* GNSS_SDR_ACQUISITION_INTERFACE */ diff --git a/src/core/interfaces/channel_interface.h b/src/core/interfaces/channel_interface.h index 48232c674..db449941c 100644 --- a/src/core/interfaces/channel_interface.h +++ b/src/core/interfaces/channel_interface.h @@ -53,6 +53,7 @@ class ChannelInterface : public GNSSBlockInterface public: virtual Gnss_Signal get_signal() const = 0; virtual void start_acquisition() = 0; + virtual void stop_channel() = 0; virtual void set_signal(const Gnss_Signal&) = 0; }; diff --git a/src/core/interfaces/tracking_interface.h b/src/core/interfaces/tracking_interface.h index 010036d72..da2b3c41b 100644 --- a/src/core/interfaces/tracking_interface.h +++ b/src/core/interfaces/tracking_interface.h @@ -56,6 +56,7 @@ class TrackingInterface : public GNSSBlockInterface { public: virtual void start_tracking() = 0; + virtual void stop_tracking() = 0; virtual void set_gnss_synchro(Gnss_Synchro* gnss_synchro) = 0; virtual void set_channel(unsigned int channel) = 0; }; diff --git a/src/core/libs/gnss_sdr_supl_client.cc b/src/core/libs/gnss_sdr_supl_client.cc index 4d3668adc..b95221856 100644 --- a/src/core/libs/gnss_sdr_supl_client.cc +++ b/src/core/libs/gnss_sdr_supl_client.cc @@ -268,7 +268,7 @@ void gnss_sdr_supl_client::read_supl_data() gps_almanac_iterator->second.d_sqrt_A = static_cast(a->A_sqrt) * pow(2.0, -11); gps_almanac_iterator->second.d_OMEGA_DOT = static_cast(a->OMEGA_dot) * pow(2.0, -38); gps_almanac_iterator->second.d_Toa = static_cast(a->toa) * pow(2.0, 12); - gps_almanac_iterator->second.d_e_eccentricity = static_cast(a->toa) * pow(2.0, -21); + gps_almanac_iterator->second.d_e_eccentricity = static_cast(a->e) * pow(2.0, -21); gps_almanac_iterator->second.d_M_0 = static_cast(a->M0) * pow(2.0, -23); } } @@ -415,6 +415,147 @@ bool gnss_sdr_supl_client::save_ephemeris_map_xml(const std::string file_name, s } +bool gnss_sdr_supl_client::load_gal_ephemeris_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + gal_ephemeris_map.clear(); + xml >> boost::serialization::make_nvp("GNSS-SDR_gal_ephemeris_map", this->gal_ephemeris_map); + LOG(INFO) << "Loaded Ephemeris map data with " << this->gal_ephemeris_map.size() << " satellites"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool save_gal_ephemeris_map_xml(const std::string file_name, std::map eph_map) +{ + if (eph_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_ephemeris_map", eph_map); + LOG(INFO) << "Saved Galileo ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save Galileo ephemeris, map is empty"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_cnav_ephemeris_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + gps_cnav_ephemeris_map.clear(); + xml >> boost::serialization::make_nvp("GNSS-SDR_cnav_ephemeris_map", this->gps_cnav_ephemeris_map); + LOG(INFO) << "Loaded Ephemeris map data with " << this->gps_cnav_ephemeris_map.size() << " satellites"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool save_cnav_ephemeris_map_xml(const std::string file_name, std::map eph_map) +{ + if (eph_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_cnav_ephemeris_map", eph_map); + LOG(INFO) << "Saved GPS CNAV ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save GPS CNAV ephemeris, map is empty"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_gnav_ephemeris_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + gps_cnav_ephemeris_map.clear(); + xml >> boost::serialization::make_nvp("GNSS-SDR_gnav_ephemeris_map", this->glonass_gnav_ephemeris_map); + LOG(INFO) << "Loaded GLONASS ephemeris map data with " << this->gps_cnav_ephemeris_map.size() << " satellites"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool save_gnav_ephemeris_map_xml(const std::string file_name, std::map eph_map) +{ + if (eph_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gnav_ephemeris_map", eph_map); + LOG(INFO) << "Saved GLONASS GNAV ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save GLONASS GNAV ephemeris, map is empty"; + return false; + } + return true; +} + + bool gnss_sdr_supl_client::load_utc_xml(const std::string file_name) { std::ifstream ifs; @@ -422,7 +563,7 @@ bool gnss_sdr_supl_client::load_utc_xml(const std::string file_name) { ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); boost::archive::xml_iarchive xml(ifs); - xml >> boost::serialization::make_nvp("GNSS-SDR_utc_map", this->gps_utc); + xml >> boost::serialization::make_nvp("GNSS-SDR_utc_model", this->gps_utc); LOG(INFO) << "Loaded UTC model data"; } catch (std::exception& e) @@ -434,17 +575,17 @@ bool gnss_sdr_supl_client::load_utc_xml(const std::string file_name) } -bool gnss_sdr_supl_client::save_utc_map_xml(const std::string file_name, std::map utc_map) +bool gnss_sdr_supl_client::save_utc_xml(const std::string file_name, Gps_Utc_Model& utc) { - if (utc_map.empty() == false) + if (utc.valid) { std::ofstream ofs; try { ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_utc_map", utc_map); - LOG(INFO) << "Saved UTC Model data"; + xml << boost::serialization::make_nvp("GNSS-SDR_utc_model", utc); + LOG(INFO) << "Saved GPS UTC Model data"; } catch (std::exception& e) { @@ -454,7 +595,99 @@ bool gnss_sdr_supl_client::save_utc_map_xml(const std::string file_name, std::ma } else { - LOG(WARNING) << "Failed to save UTC model, map is empty"; + LOG(WARNING) << "Failed to save GPS UTC model, no valid data"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_cnav_utc_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + xml >> boost::serialization::make_nvp("GNSS-SDR_cnav_utc_model", this->gps_cnav_utc); + LOG(INFO) << "Loaded CNAV UTC model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::save_cnav_utc_xml(const std::string file_name, Gps_CNAV_Utc_Model& utc) +{ + if (utc.valid) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_cnav_utc_model", utc); + LOG(INFO) << "Saved GPS CNAV UTC model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save GPS CNAV UTC model, no valid data"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_gal_utc_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + xml >> boost::serialization::make_nvp("GNSS-SDR_gal_utc_model", this->gal_utc); + LOG(INFO) << "Loaded Galileo UTC model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::save_gal_utc_xml(const std::string file_name, Galileo_Utc_Model& utc) +{ + if (utc.flag_utc_model) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_utc_model", utc); + LOG(INFO) << "Saved Galileo UTC Model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save Galileo UTC model, no valid data"; return false; } return true; @@ -468,7 +701,7 @@ bool gnss_sdr_supl_client::load_iono_xml(const std::string file_name) { ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); boost::archive::xml_iarchive xml(ifs); - xml >> boost::serialization::make_nvp("GNSS-SDR_iono_map", this->gps_iono); + xml >> boost::serialization::make_nvp("GNSS-SDR_iono_model", this->gps_iono); LOG(INFO) << "Loaded IONO model data"; } catch (std::exception& e) @@ -480,16 +713,16 @@ bool gnss_sdr_supl_client::load_iono_xml(const std::string file_name) } -bool gnss_sdr_supl_client::save_iono_map_xml(const std::string file_name, std::map iono_map) +bool gnss_sdr_supl_client::save_iono_xml(const std::string file_name, Gps_Iono& iono) { - if (iono_map.empty() == false) + if (iono.valid) { std::ofstream ofs; try { ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_iono_map", iono_map); + xml << boost::serialization::make_nvp("GNSS-SDR_iono_model", iono); LOG(INFO) << "Saved IONO Model data"; } catch (std::exception& e) @@ -507,6 +740,192 @@ bool gnss_sdr_supl_client::save_iono_map_xml(const std::string file_name, std::m } +bool gnss_sdr_supl_client::load_gal_iono_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + xml >> boost::serialization::make_nvp("GNSS-SDR_gal_iono_model", this->gal_iono); + LOG(INFO) << "Loaded Galileo IONO model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::save_gal_iono_xml(const std::string file_name, Galileo_Iono& iono) +{ + if (iono.ai0_5 != 0.0) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_iono_model", iono); + LOG(INFO) << "Saved Galileo IONO Model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save Galileo IONO model, map is empty"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_gps_almanac_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + gps_almanac_map.clear(); + xml >> boost::serialization::make_nvp("GNSS-SDR_gps_almanac_map", this->gps_almanac_map); + LOG(INFO) << "Loaded GPS almanac map data with " << this->gps_almanac_map.size() << " satellites"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::save_gps_almanac_xml(const std::string file_name, std::map gps_almanac_map) +{ + if (gps_almanac_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gps_almanac_map", gps_almanac_map); + LOG(INFO) << "Saved GPS almanac data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save GPS almanac, map is empty"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_gal_almanac_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + gal_almanac_map.clear(); + xml >> boost::serialization::make_nvp("GNSS-SDR_gal_almanac_map", this->gal_almanac_map); + LOG(INFO) << "Loaded Galileo almanac map data with " << this->gal_almanac_map.size() << " satellites"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::save_gal_almanac_xml(const std::string file_name, std::map gal_almanac_map) +{ + if (gal_almanac_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_almanac_map", gal_almanac_map); + LOG(INFO) << "Saved Galileo almanac data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save Galileo almanac, map is empty"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_glo_utc_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + xml >> boost::serialization::make_nvp("GNSS-SDR_glo_utc_model", this->glo_gnav_utc); + LOG(INFO) << "Loaded UTC model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::save_glo_utc_xml(const std::string file_name, Glonass_Gnav_Utc_Model& utc) +{ + if (utc.valid) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_glo_utc_model", utc); + LOG(INFO) << "Saved Glonass UTC Model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save Glonass UTC model, no valid data"; + return false; + } + return true; +} + + bool gnss_sdr_supl_client::load_ref_time_xml(const std::string file_name) { std::ifstream ifs; diff --git a/src/core/libs/gnss_sdr_supl_client.h b/src/core/libs/gnss_sdr_supl_client.h index 381045edb..52e4ed371 100644 --- a/src/core/libs/gnss_sdr_supl_client.h +++ b/src/core/libs/gnss_sdr_supl_client.h @@ -43,9 +43,17 @@ extern "C" #include "gps_iono.h" #include "gps_almanac.h" #include "gps_utc_model.h" +#include "gps_cnav_utc_model.h" #include "gps_acq_assist.h" #include "gps_ref_time.h" #include "gps_ref_location.h" +#include "gps_cnav_ephemeris.h" +#include "galileo_ephemeris.h" +#include "galileo_utc_model.h" +#include "galileo_iono.h" +#include "galileo_almanac.h" +#include "glonass_gnav_ephemeris.h" +#include "glonass_gnav_utc_model.h" #include #include #include @@ -77,15 +85,24 @@ public: int request; // ephemeris map std::map gps_ephemeris_map; + std::map gal_ephemeris_map; + std::map gps_cnav_ephemeris_map; + std::map glonass_gnav_ephemeris_map; + // almanac map std::map gps_almanac_map; + std::map gal_almanac_map; // ionospheric model Gps_Iono gps_iono; + Galileo_Iono gal_iono; // reference time Gps_Ref_Time gps_time; // UTC model Gps_Utc_Model gps_utc; + Galileo_Utc_Model gal_utc; + Gps_CNAV_Utc_Model gps_cnav_utc; + Glonass_Gnav_Utc_Model glo_gnav_utc; // reference location Gps_Ref_Location gps_ref_loc; // Acquisition Assistance map @@ -107,7 +124,7 @@ public: void read_supl_data(); /*! - * \brief Read ephemeris map from XML file + * \brief Read GPS NAV ephemeris map from XML file */ bool load_ephemeris_xml(const std::string file_name); @@ -118,16 +135,87 @@ public: std::map eph_map); /*! - * \brief Read utc model from XML file + * \brief Read GPS CNAV ephemeris map from XML file + */ + bool load_cnav_ephemeris_xml(const std::string file_name); + + /*! + * \brief Save GPS CNAV ephemeris map to XML file. + */ + bool save_cnav_ephemeris_map_xml(const std::string file_name, + std::map eph_map); + + /*! + * \brief Read Galileo ephemeris map from XML file + */ + bool load_gal_ephemeris_xml(const std::string file_name); + + /*! + * \brief Save Galileo ephemeris map to XML file. + */ + bool save_gal_ephemeris_map_xml(const std::string file_name, + std::map eph_map); + + /*! + * \brief Read GLONASS GNAV ephemeris map from XML file + */ + bool load_gnav_ephemeris_xml(const std::string file_name); + + /*! + * \brief Save GLONASS GNAV ephemeris map to XML file. + */ + bool save_gnav_ephemeris_map_xml(const std::string file_name, + std::map eph_map); + + /*! + * \brief Read GPS utc model from XML file */ bool load_utc_xml(const std::string file_name); /*! - * \brief Save utc model map to XML file - * To be called by ControlThread::gps_utc_model_data_write_to_XML() + * \brief Save UTC model map to XML file */ - bool save_utc_map_xml(const std::string file_name, - std::map utc_map); + bool save_utc_xml(const std::string file_name, Gps_Utc_Model& utc); + + /*! + * \brief Read CNAV GPS utc model from XML file + */ + bool load_cnav_utc_xml(const std::string file_name); + + /*! + * \brief Save CNAV UTC model map to XML file + */ + bool save_cnav_utc_xml(const std::string file_name, Gps_CNAV_Utc_Model& utc); + + /*! + * \brief Read Galileo utc model from XML file + */ + bool load_gal_utc_xml(const std::string file_name); + + /*! + * \brief Save Galileo UTC model map to XML file + */ + bool save_gal_utc_xml(const std::string file_name, Galileo_Utc_Model& utc); + + /*! + * \brief Read Galileo almanac map from XML file + */ + bool load_gal_almanac_xml(const std::string file_name); + + /*! + * \brief Save Galileo almanac map to XML file + */ + bool save_gal_almanac_xml(const std::string file_name, std::map gal_almanac); + + /*! + * \brief Read GPS almanac map from XML file + */ + bool load_gps_almanac_xml(const std::string file_name); + + /*! + * \brief Save GPS almanac map to XML file + */ + bool save_gps_almanac_xml(const std::string file_name, std::map gps_almanac_map); /*! * \brief Read iono from XML file @@ -137,8 +225,27 @@ public: /*! * \brief Save iono map to XML file */ - bool save_iono_map_xml(const std::string file_name, - std::map iono_map); + bool save_iono_xml(const std::string file_name, Gps_Iono& iono); + + /*! + * \brief Read Galileo iono from XML file + */ + bool load_gal_iono_xml(const std::string file_name); + + /*! + * \brief Save Galileo iono map to XML file + */ + bool save_gal_iono_xml(const std::string file_name, Galileo_Iono& iono); + + /*! + * \brief Read Glonass utc model from XML file + */ + bool load_glo_utc_xml(const std::string file_name); + + /*! + * \brief Save Glonass UTC model map to XML file + */ + bool save_glo_utc_xml(const std::string file_name, Glonass_Gnav_Utc_Model& utc); /*! * \brief Read ref time from XML file @@ -166,6 +273,7 @@ public: * Prints SUPL data to std::cout. Use it for debug purposes only. */ void print_assistance(); + gnss_sdr_supl_client(); ~gnss_sdr_supl_client(); }; diff --git a/src/core/receiver/CMakeLists.txt b/src/core/receiver/CMakeLists.txt index decc866d9..e0246a06f 100644 --- a/src/core/receiver/CMakeLists.txt +++ b/src/core/receiver/CMakeLists.txt @@ -24,6 +24,7 @@ set(GNSS_RECEIVER_SOURCES gnss_block_factory.cc gnss_flowgraph.cc in_memory_configuration.cc + tcp_cmd_interface.cc ) set(GNSS_RECEIVER_HEADERS diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc index 8eb49563c..a73d2b446 100644 --- a/src/core/receiver/control_thread.cc +++ b/src/core/receiver/control_thread.cc @@ -47,6 +47,8 @@ #include "gps_iono.h" #include "gps_utc_model.h" #include "gps_almanac.h" +#include "glonass_gnav_ephemeris.h" +#include "glonass_gnav_utc_model.h" #include #include #include @@ -78,6 +80,7 @@ ControlThread::ControlThread() configuration_ = std::make_shared(FLAGS_c); } delete_configuration_ = false; + restart_ = false; init(); } @@ -98,6 +101,12 @@ ControlThread::~ControlThread() } +void ControlThread::telecommand_listener() +{ + int tcp_cmd_port = configuration_->property("Channel.telecontrol_tcp_port", 3333); + cmd_interface_.run_cmd_server(tcp_cmd_port); +} + /* * Runs the control thread that manages the receiver control plane * @@ -107,7 +116,7 @@ ControlThread::~ControlThread() * while (flowgraph_->running() && !stop)_{ * 3- Read control messages and process them } */ -void ControlThread::run() +int ControlThread::run() { // Connect the flowgraph try @@ -117,7 +126,7 @@ void ControlThread::run() catch (const std::exception &e) { LOG(ERROR) << e.what(); - return; + return 0; } if (flowgraph_->connected()) { @@ -126,7 +135,7 @@ void ControlThread::run() else { LOG(ERROR) << "Unable to connect flowgraph"; - return; + return 0; } // Start the flowgraph flowgraph_->start(); @@ -137,7 +146,7 @@ void ControlThread::run() else { LOG(ERROR) << "Unable to start flowgraph"; - return; + return 0; } //launch GNSS assistance process AFTER the flowgraph is running because the GNURadio asynchronous queues must be already running to transport msgs @@ -146,8 +155,11 @@ void ControlThread::run() keyboard_thread_ = boost::thread(&ControlThread::keyboard_listener, this); sysv_queue_thread_ = boost::thread(&ControlThread::sysv_queue_listener, this); - bool enable_FPGA = configuration_->property("Channel.enable_FPGA", false); + //start the telecommand listener thread + cmd_interface_thread_ = boost::thread(&ControlThread::telecommand_listener, this); + + bool enable_FPGA = configuration_->property("Channel.enable_FPGA", false); if (enable_FPGA == true) { flowgraph_->start_acquisition_helper(); @@ -165,17 +177,28 @@ void ControlThread::run() stop_ = true; flowgraph_->disconnect(); - //Join keyboard thread +//Join keyboard thread #ifdef OLD_BOOST keyboard_thread_.timed_join(boost::posix_time::seconds(1)); sysv_queue_thread_.timed_join(boost::posix_time::seconds(1)); + cmd_interface_thread_.timed_join(boost::posix_time::seconds(1)); #endif #ifndef OLD_BOOST keyboard_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000)); sysv_queue_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000)); + cmd_interface_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000)); #endif LOG(INFO) << "Flowgraph stopped"; + + if (restart_) + { + return 42; //signal the gnss-sdr-harness.sh to restart the receiver program + } + else + { + return 0; //normal shutdown + } } @@ -187,6 +210,7 @@ void ControlThread::set_control_queue(gr::msg_queue::sptr control_queue) return; } control_queue_ = control_queue; + cmd_interface_.set_msg_queue(control_queue_); } @@ -199,58 +223,193 @@ bool ControlThread::read_assistance_from_XML() bool ret = false; // getting names from the config file, if available std::string eph_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_xml", eph_default_xml_filename); - std::string utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_utc_model.xml", utc_default_xml_filename); + std::string utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_utc_model_xml", utc_default_xml_filename); std::string iono_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_iono_xml", iono_default_xml_filename); + std::string gal_iono_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_iono_xml", gal_iono_default_xml_filename); std::string ref_time_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_time_xml", ref_time_default_xml_filename); std::string ref_location_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_location_xml", ref_location_default_xml_filename); + std::string eph_gal_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_ephemeris_xml", eph_gal_default_xml_filename); + std::string eph_cnav_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_cnav_ephemeris_xml", eph_cnav_default_xml_filename); + std::string gal_utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_utc_model_xml", gal_utc_default_xml_filename); + std::string cnav_utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_cnav_utc_model_xml", cnav_utc_default_xml_filename); + std::string eph_glo_xml_filename = configuration_->property("GNSS-SDR.SUPL_glo_ephemeris_xml", eph_glo_gnav_default_xml_filename); + std::string glo_utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_glo_utc_model_xml", glo_utc_default_xml_filename); + std::string gal_almanac_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_almanacl_xml", gal_almanac_default_xml_filename); + std::string gps_almanac_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_almanacl_xml", gps_almanac_default_xml_filename); - std::cout << "SUPL: Try read GPS ephemeris from XML file " << eph_xml_filename << std::endl; - if (supl_client_ephemeris_.load_ephemeris_xml(eph_xml_filename) == true) + if (configuration_->property("GNSS-SDR.AGNSS_XML_enabled", false) == true) { - std::map::const_iterator gps_eph_iter; - for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.cbegin(); - gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); - gps_eph_iter++) + eph_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_ephemeris_xml", eph_default_xml_filename); + utc_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_utc_model_xml", utc_default_xml_filename); + iono_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_iono_xml", iono_default_xml_filename); + gal_iono_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gal_iono_xml", gal_iono_default_xml_filename); + ref_time_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_ref_time_xml", ref_time_default_xml_filename); + ref_location_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_ref_location_xml", ref_location_default_xml_filename); + eph_gal_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gal_ephemeris_xml", eph_gal_default_xml_filename); + eph_cnav_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_cnav_ephemeris_xml", eph_cnav_default_xml_filename); + gal_utc_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gal_utc_model_xml", gal_utc_default_xml_filename); + cnav_utc_xml_filename = configuration_->property("GNSS-SDR.AGNSS_cnav_utc_model_xml", cnav_utc_default_xml_filename); + eph_glo_xml_filename = configuration_->property("GNSS-SDR.AGNSS_glo_ephemeris_xml", eph_glo_gnav_default_xml_filename); + glo_utc_xml_filename = configuration_->property("GNSS-SDR.AGNSS_glo_utc_model_xml", glo_utc_default_xml_filename); + gal_almanac_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gal_almanacl_xml", gal_almanac_default_xml_filename); + } + + std::cout << "Trying to read GNSS ephemeris from XML file(s)..." << std::endl; + + if (configuration_->property("Channels_1C.count", 0) > 0) + { + if (supl_client_ephemeris_.load_ephemeris_xml(eph_xml_filename) == true) { - std::cout << "SUPL: Read XML Ephemeris for GPS SV " << gps_eph_iter->first << std::endl; - std::shared_ptr tmp_obj = std::make_shared(gps_eph_iter->second); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::map::const_iterator gps_eph_iter; + for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.cbegin(); + gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); + gps_eph_iter++) + { + std::cout << "From XML file: Read NAV ephemeris for satellite " << Gnss_Satellite("GPS", gps_eph_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gps_eph_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + ret = true; + } + + if (supl_client_acquisition_.load_utc_xml(utc_xml_filename) == true) + { + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_utc); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::cout << "From XML file: Read GPS UTC model parameters." << std::endl; + ret = true; + } + + if (supl_client_acquisition_.load_iono_xml(iono_xml_filename) == true) + { + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_iono); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::cout << "From XML file: Read GPS ionosphere model parameters." << std::endl; + ret = true; + } + + if (supl_client_ephemeris_.load_gps_almanac_xml(gps_almanac_xml_filename) == true) + { + std::map::const_iterator gps_alm_iter; + for (gps_alm_iter = supl_client_ephemeris_.gps_almanac_map.cbegin(); + gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.cend(); + gps_alm_iter++) + { + std::cout << "From XML file: Read GPS almanac for satellite " << Gnss_Satellite("GPS", gps_alm_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gps_alm_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + ret = true; } - ret = true; } - else + + if ((configuration_->property("Channels_1B.count", 0) > 0) or (configuration_->property("Channels_5X.count", 0) > 0)) { - std::cout << "ERROR: SUPL client error reading XML" << std::endl; - std::cout << "Disabling SUPL assistance..." << std::endl; + if (supl_client_ephemeris_.load_gal_ephemeris_xml(eph_gal_xml_filename) == true) + { + std::map::const_iterator gal_eph_iter; + for (gal_eph_iter = supl_client_ephemeris_.gal_ephemeris_map.cbegin(); + gal_eph_iter != supl_client_ephemeris_.gal_ephemeris_map.cend(); + gal_eph_iter++) + { + std::cout << "From XML file: Read ephemeris for satellite " << Gnss_Satellite("Galileo", gal_eph_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gal_eph_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + ret = true; + } + + if (supl_client_acquisition_.load_gal_iono_xml(gal_iono_xml_filename) == true) + { + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gal_iono); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::cout << "From XML file: Read Galileo ionosphere model parameters." << std::endl; + ret = true; + } + + if (supl_client_acquisition_.load_gal_utc_xml(gal_utc_xml_filename) == true) + { + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gal_utc); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::cout << "From XML file: Read Galileo UTC model parameters." << std::endl; + ret = true; + } + + if (supl_client_ephemeris_.load_gal_almanac_xml(gal_almanac_xml_filename) == true) + { + std::map::const_iterator gal_alm_iter; + for (gal_alm_iter = supl_client_ephemeris_.gal_almanac_map.cbegin(); + gal_alm_iter != supl_client_ephemeris_.gal_almanac_map.cend(); + gal_alm_iter++) + { + std::cout << "From XML file: Read Galileo almanac for satellite " << Gnss_Satellite("Galileo", gal_alm_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gal_alm_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + ret = true; + } } - // Only look for {utc, iono, ref time, ref location} if SUPL is enabled + + if ((configuration_->property("Channels_2S.count", 0) > 0) or (configuration_->property("Channels_L5.count", 0) > 0)) + { + if (supl_client_ephemeris_.load_cnav_ephemeris_xml(eph_cnav_xml_filename) == true) + { + std::map::const_iterator gps_cnav_eph_iter; + for (gps_cnav_eph_iter = supl_client_ephemeris_.gps_cnav_ephemeris_map.cbegin(); + gps_cnav_eph_iter != supl_client_ephemeris_.gps_cnav_ephemeris_map.cend(); + gps_cnav_eph_iter++) + { + std::cout << "From XML file: Read CNAV ephemeris for satellite " << Gnss_Satellite("GPS", gps_cnav_eph_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gps_cnav_eph_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + ret = true; + } + + if (supl_client_acquisition_.load_cnav_utc_xml(cnav_utc_xml_filename) == true) + { + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_cnav_utc); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::cout << "From XML file: Read GPS CNAV UTC model parameters." << std::endl; + ret = true; + } + } + + if ((configuration_->property("Channels_1G.count", 0) > 0) or (configuration_->property("Channels_2G.count", 0) > 0)) + { + if (supl_client_ephemeris_.load_gnav_ephemeris_xml(eph_glo_xml_filename) == true) + { + std::map::const_iterator glo_gnav_eph_iter; + for (glo_gnav_eph_iter = supl_client_ephemeris_.glonass_gnav_ephemeris_map.cbegin(); + glo_gnav_eph_iter != supl_client_ephemeris_.glonass_gnav_ephemeris_map.cend(); + glo_gnav_eph_iter++) + { + std::cout << "From XML file: Read GLONASS GNAV ephemeris for satellite " << Gnss_Satellite("GLONASS", glo_gnav_eph_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(glo_gnav_eph_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + ret = true; + } + + if (supl_client_acquisition_.load_glo_utc_xml(glo_utc_xml_filename) == true) + { + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.glo_gnav_utc); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::cout << "From XML file: Read GLONASS UTC model parameters." << std::endl; + ret = true; + } + } + + if (ret == false) + { + std::cout << "Error reading XML files" << std::endl; + std::cout << "Disabling GNSS assistance..." << std::endl; + } + + // Only look for {ref time, ref location} if SUPL is enabled bool enable_gps_supl_assistance = configuration_->property("GNSS-SDR.SUPL_gps_enabled", false); if (enable_gps_supl_assistance == true) { - // Try to read UTC model from XML - if (supl_client_acquisition_.load_utc_xml(utc_xml_filename) == true) - { - LOG(INFO) << "SUPL: Read XML UTC model"; - std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_utc); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - else - { - LOG(INFO) << "SUPL: couldn't read UTC model XML"; - } - - // Try to read Iono model from XML - if (supl_client_acquisition_.load_iono_xml(iono_xml_filename) == true) - { - LOG(INFO) << "SUPL: Read XML IONO model"; - std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_iono); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - else - { - LOG(INFO) << "SUPL: couldn't read IONO model XML"; - } - // Try to read Ref Time from XML if (supl_client_acquisition_.load_ref_time_xml(ref_time_xml_filename) == true) { @@ -260,7 +419,7 @@ bool ControlThread::read_assistance_from_XML() } else { - LOG(INFO) << "SUPL: couldn't read Ref Time XML"; + LOG(INFO) << "SUPL: could not read Ref Time XML"; } // Try to read Ref Location from XML @@ -272,7 +431,7 @@ bool ControlThread::read_assistance_from_XML() } else { - LOG(INFO) << "SUPL: couldn't read Ref Location XML"; + LOG(INFO) << "SUPL: could not read Ref Location XML"; } } @@ -285,35 +444,48 @@ void ControlThread::assist_GNSS() //######### GNSS Assistance ################################# // GNSS Assistance configuration bool enable_gps_supl_assistance = configuration_->property("GNSS-SDR.SUPL_gps_enabled", false); - if (enable_gps_supl_assistance == true) - //SUPL SERVER TEST. Not operational yet! + bool enable_agnss_xml = configuration_->property("GNSS-SDR.AGNSS_XML_enabled", false); + if ((enable_gps_supl_assistance == true) and (enable_agnss_xml == false)) { std::cout << "SUPL RRLP GPS assistance enabled!" << std::endl; - std::string default_acq_server = "supl.nokia.com"; + std::string default_acq_server = "supl.google.com"; std::string default_eph_server = "supl.google.com"; supl_client_ephemeris_.server_name = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_server", default_acq_server); supl_client_acquisition_.server_name = configuration_->property("GNSS-SDR.SUPL_gps_acquisition_server", default_eph_server); supl_client_ephemeris_.server_port = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_port", 7275); supl_client_acquisition_.server_port = configuration_->property("GNSS-SDR.SUPL_gps_acquisition_port", 7275); supl_mcc = configuration_->property("GNSS-SDR.SUPL_MCC", 244); - supl_mns = configuration_->property("GNSS-SDR.SUPL_MNS", 5); + supl_mns = configuration_->property("GNSS-SDR.SUPL_MNC ", 5); std::string default_lac = "0x59e2"; std::string default_ci = "0x31b0"; + std::string supl_lac_s = configuration_->property("GNSS-SDR.SUPL_LAC", default_lac); + std::string supl_ci_s = configuration_->property("GNSS-SDR.SUPL_CI", default_ci); try { - supl_lac = boost::lexical_cast(configuration_->property("GNSS-SDR.SUPL_LAC", default_lac)); + supl_lac = std::stoi(supl_lac_s, nullptr, 0); } - catch (boost::bad_lexical_cast &) + catch (const std::invalid_argument &ia) + { + std::cerr << "Invalid argument for SUPL LAC: " << ia.what() << '\n'; + supl_lac = -1; + } + try + { + supl_ci = std::stoi(supl_ci_s, nullptr, 0); + } + catch (const std::invalid_argument &ia) + { + std::cerr << "Invalid argument for SUPL CI: " << ia.what() << '\n'; + supl_ci = -1; + } + + if (supl_lac < 0 or supl_lac > 65535) { supl_lac = 0x59e2; } - try - { - supl_ci = boost::lexical_cast(configuration_->property("GNSS-SDR.SUPL_CI", default_ci)); - } - catch (boost::bad_lexical_cast &) + if (supl_ci < 0 or supl_ci > 268435455) // 2^16 for GSM and CDMA, 2^28 for UMTS and LTE networks { supl_ci = 0x31b0; } @@ -324,7 +496,8 @@ void ControlThread::assist_GNSS() // read assistance from file if (read_assistance_from_XML()) { - std::cout << "GPS assistance data loaded from local XML file." << std::endl; + std::cout << "GNSS assistance data loaded from local XML file(s)." << std::endl; + std::cout << "No SUPL request has been performed." << std::endl; } } else @@ -332,7 +505,7 @@ void ControlThread::assist_GNSS() // Request ephemeris from SUPL server int error; supl_client_ephemeris_.request = 1; - std::cout << "SUPL: Try to read GPS ephemeris from SUPL server..." << std::endl; + std::cout << "SUPL: Try to read GPS ephemeris data from SUPL server..." << std::endl; error = supl_client_ephemeris_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci); if (error == 0) { @@ -341,35 +514,35 @@ void ControlThread::assist_GNSS() gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); gps_eph_iter++) { - std::cout << "SUPL: Received Ephemeris for GPS SV " << gps_eph_iter->first << std::endl; + std::cout << "SUPL: Received ephemeris data for satellite " << Gnss_Satellite("GPS", gps_eph_iter->second.i_satellite_PRN) << std::endl; std::shared_ptr tmp_obj = std::make_shared(gps_eph_iter->second); flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); } - //Save ephemeris to XML file + // Save ephemeris to XML file std::string eph_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_xml", eph_default_xml_filename); if (supl_client_ephemeris_.save_ephemeris_map_xml(eph_xml_filename, supl_client_ephemeris_.gps_ephemeris_map) == true) { - std::cout << "SUPL: XML Ephemeris file created" << std::endl; + std::cout << "SUPL: XML ephemeris data file created" << std::endl; } else { - std::cout << "SUPL: Failed to create XML Ephemeris file" << std::endl; + std::cout << "SUPL: Failed to create XML ephemeris data file" << std::endl; } } else { - std::cout << "ERROR: SUPL client for Ephemeris returned " << error << std::endl; - std::cout << "Please check internet connection and SUPL server configuration" << error << std::endl; - std::cout << "Trying to read ephemeris from XML file" << std::endl; + std::cout << "ERROR: SUPL client request for ephemeris data returned " << error << std::endl; + std::cout << "Please check your network connectivity and SUPL server configuration" << std::endl; + std::cout << "Trying to read AGNSS data from local XML file(s)..." << std::endl; if (read_assistance_from_XML() == false) { - std::cout << "ERROR: Could not read Ephemeris file: Disabling SUPL assistance." << std::endl; + std::cout << "ERROR: Could not read XML files: Disabling SUPL assistance." << std::endl; } } - // Request almanac , IONO and UTC Model + // Request almanac, IONO and UTC Model data supl_client_ephemeris_.request = 0; - std::cout << "SUPL: Try read Almanac, Iono, Utc Model, Ref Time and Ref Location from SUPL server..." << std::endl; + std::cout << "SUPL: Try to read Almanac, Iono, Utc Model, Ref Time and Ref Location data from SUPL server..." << std::endl; error = supl_client_ephemeris_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci); if (error == 0) { @@ -378,33 +551,51 @@ void ControlThread::assist_GNSS() gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.cend(); gps_alm_iter++) { - std::cout << "SUPL: Received Almanac for GPS SV " << gps_alm_iter->first << std::endl; + std::cout << "SUPL: Received almanac data for satellite " << Gnss_Satellite("GPS", gps_alm_iter->second.i_satellite_PRN) << std::endl; std::shared_ptr tmp_obj = std::make_shared(gps_alm_iter->second); flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); } if (supl_client_ephemeris_.gps_iono.valid == true) { - std::cout << "SUPL: Received GPS Iono" << std::endl; + std::cout << "SUPL: Received GPS Ionosphere model parameters" << std::endl; std::shared_ptr tmp_obj = std::make_shared(supl_client_ephemeris_.gps_iono); flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); } if (supl_client_ephemeris_.gps_utc.valid == true) { - std::cout << "SUPL: Received GPS UTC Model" << std::endl; + std::cout << "SUPL: Received GPS UTC model parameters" << std::endl; std::shared_ptr tmp_obj = std::make_shared(supl_client_ephemeris_.gps_utc); flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); } + // Save iono and UTC model data to xml file + std::string iono_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_iono_xml", iono_default_xml_filename); + if (supl_client_ephemeris_.save_iono_xml(iono_xml_filename, supl_client_ephemeris_.gps_iono) == true) + { + std::cout << "SUPL: Iono data file created" << std::endl; + } + else + { + std::cout << "SUPL: Failed to create Iono data file" << std::endl; + } + std::string utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_utc_model_xml", utc_default_xml_filename); + if (supl_client_ephemeris_.save_utc_xml(utc_xml_filename, supl_client_ephemeris_.gps_utc) == true) + { + std::cout << "SUPL: UTC model data file created" << std::endl; + } + else + { + std::cout << "SUPL: Failed to create UTC model data file" << std::endl; + } } else { - std::cout << "ERROR: SUPL client for Almanac returned " << error << std::endl; - std::cout << "Please check internet connection and SUPL server configuration" << error << std::endl; - std::cout << "Disabling SUPL assistance." << std::endl; + std::cout << "ERROR: SUPL client for almanac data returned " << error << std::endl; + std::cout << "Please check your network connectivity and SUPL server configuration" << std::endl; } // Request acquisition assistance supl_client_acquisition_.request = 2; - std::cout << "SUPL: Try read Acquisition assistance from SUPL server..." << std::endl; + std::cout << "SUPL: Try to read acquisition assistance data from SUPL server..." << std::endl; error = supl_client_acquisition_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci); if (error == 0) { @@ -413,30 +604,39 @@ void ControlThread::assist_GNSS() gps_acq_iter != supl_client_acquisition_.gps_acq_map.cend(); gps_acq_iter++) { - std::cout << "SUPL: Received Acquisition assistance for GPS SV " << gps_acq_iter->first << std::endl; + std::cout << "SUPL: Received acquisition assistance data for satellite " << Gnss_Satellite("GPS", gps_acq_iter->second.i_satellite_PRN) << std::endl; global_gps_acq_assist_map.write(gps_acq_iter->second.i_satellite_PRN, gps_acq_iter->second); } if (supl_client_acquisition_.gps_ref_loc.valid == true) { - std::cout << "SUPL: Received Ref Location (Acquisition Assistance)" << std::endl; + std::cout << "SUPL: Received Ref Location data (Acquisition Assistance)" << std::endl; std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_ref_loc); flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); } if (supl_client_acquisition_.gps_time.valid == true) { - std::cout << "SUPL: Received Ref Time (Acquisition Assistance)" << std::endl; + std::cout << "SUPL: Received Ref Time data (Acquisition Assistance)" << std::endl; std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_time); flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); } } else { - std::cout << "ERROR: SUPL client for Acquisition assistance returned " << error << std::endl; - std::cout << "Please check internet connection and SUPL server configuration" << error << std::endl; - std::cout << "Disabling SUPL assistance.." << std::endl; + std::cout << "ERROR: SUPL client for acquisition assistance returned " << error << std::endl; + std::cout << "Please check your network connectivity and SUPL server configuration" << std::endl; + std::cout << "Disabling SUPL acquisition assistance." << std::endl; } } } + + if ((enable_gps_supl_assistance == false) and (enable_agnss_xml == true)) + { + // read assistance from file + if (read_assistance_from_XML()) + { + std::cout << "GNSS assistance data loaded from local XML file(s)." << std::endl; + } + } } @@ -444,6 +644,7 @@ void ControlThread::init() { // Instantiates a control queue, a GNSS flowgraph, and a control message factory control_queue_ = gr::msg_queue::make(0); + cmd_interface_.set_msg_queue(control_queue_); //set also the queue pointer for the telecommand thread try { flowgraph_ = std::make_shared(configuration_, control_queue_); @@ -510,6 +711,12 @@ void ControlThread::apply_action(unsigned int what) stop_ = true; applied_actions_++; break; + case 1: + DLOG(INFO) << "Received action RESTART"; + stop_ = true; + restart_ = true; + applied_actions_++; + break; default: DLOG(INFO) << "Unrecognized action."; break; diff --git a/src/core/receiver/control_thread.h b/src/core/receiver/control_thread.h index c49ddba53..ffc2ffa39 100644 --- a/src/core/receiver/control_thread.h +++ b/src/core/receiver/control_thread.h @@ -37,6 +37,7 @@ #include "control_message_factory.h" #include "gnss_sdr_supl_client.h" +#include "tcp_cmd_interface.h" #include #include #include @@ -82,7 +83,7 @@ public: * * - Read control messages and process them; } */ - void run(); + int run(); /*! * \brief Sets the control_queue @@ -113,6 +114,10 @@ public: } private: + //Telecommand TCP interface + TcpCmdInterface cmd_interface_; + void telecommand_listener(); + boost::thread cmd_interface_thread_; //SUPL assistance classes gnss_sdr_supl_client supl_client_acquisition_; gnss_sdr_supl_client supl_client_ephemeris_; @@ -150,6 +155,7 @@ private: std::shared_ptr control_message_factory_; std::shared_ptr>> control_messages_; bool stop_; + bool restart_; bool delete_configuration_; unsigned int processed_control_messages_; unsigned int applied_actions_; @@ -167,6 +173,15 @@ private: const std::string iono_default_xml_filename = "./gps_iono.xml"; const std::string ref_time_default_xml_filename = "./gps_ref_time.xml"; const std::string ref_location_default_xml_filename = "./gps_ref_location.xml"; + const std::string eph_gal_default_xml_filename = "./gal_ephemeris.xml"; + const std::string eph_cnav_default_xml_filename = "./gps_cnav_ephemeris.xml"; + const std::string gal_iono_default_xml_filename = "./gal_iono.xml"; + const std::string gal_utc_default_xml_filename = "./gal_utc_model.xml"; + const std::string cnav_utc_default_xml_filename = "./gps_cnav_utc_model.xml"; + const std::string eph_glo_gnav_default_xml_filename = "./glo_gnav_ephemeris.xml"; + const std::string glo_utc_default_xml_filename = "./glo_utc_model.xml"; + const std::string gal_almanac_default_xml_filename = "./gal_almanac.xml"; + const std::string gps_almanac_default_xml_filename = "./gps_almanac.xml"; }; #endif /*GNSS_SDR_CONTROL_THREAD_H_*/ diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index 0504da9ea..dbeabf004 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -5,6 +5,7 @@ * Luis Esteve, 2012. luis(at)epsilon-formacion.com * Carles Fernandez-Prades, 2014. cfernandez(at)cttc.es * Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com + * Javier Arribas, 2018. javiarribas(at)gmail.com * * ------------------------------------------------------------------------- * @@ -811,21 +812,40 @@ bool GNSSFlowgraph::send_telemetry_msg(pmt::pmt_t msg) /* * Applies an action to the flow graph * - * \param[in] who Who generated the action - * \param[in] what What is the action 0: acquisition failed + * \param[in] who Who generated the action: + * -> 0-199 are the channels IDs + * -> 200 is the control_thread dispatched by the control_thread apply_action + * -> 300 is the telecommand system (TC) for receiver control + * -> 400 - 599 is the TC channel control for channels 0-199 + * \param[in] what What is the action: + * --- actions from channels --- + * -> 0 acquisition failed + * -> 1 acquisition succesfull + * -> 2 tracking lost + * --- actions from TC receiver control --- + * -> 10 TC request standby mode + * -> 11 TC request coldstart + * -> 12 TC request hotstart + * -> 13 TC request warmstart + * --- actions from TC channel control --- + * -> 20 stop channel + * -> 21 start channel */ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) { std::lock_guard lock(signal_list_mutex); DLOG(INFO) << "Received " << what << " from " << who << ". Number of applied actions = " << applied_actions_; unsigned int sat = 0; - try + if (who < 200) { - sat = configuration_->property("Channel" + std::to_string(who) + ".satellite", 0); - } - catch (const std::exception& e) - { - LOG(WARNING) << e.what(); + try + { + sat = configuration_->property("Channel" + std::to_string(who) + ".satellite", 0); + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } } switch (what) { @@ -833,34 +853,42 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) DLOG(INFO) << "Channel " << who << " ACQ FAILED satellite " << channels_[who]->get_signal().get_satellite() << ", Signal " << channels_[who]->get_signal().get_signal_str(); if (sat == 0) { - switch (mapStringValues_[channels_[who]->get_signal().get_signal_str()]) + Gnss_Signal gs = channels_[who]->get_signal(); + switch (mapStringValues_[gs.get_signal_str()]) { case evGPS_1C: - available_GPS_1C_signals_.push_back(channels_[who]->get_signal()); + available_GPS_1C_signals_.remove(gs); + available_GPS_1C_signals_.push_back(gs); break; case evGPS_2S: - available_GPS_2S_signals_.push_back(channels_[who]->get_signal()); + available_GPS_2S_signals_.remove(gs); + available_GPS_2S_signals_.push_back(gs); break; case evGPS_L5: - available_GPS_L5_signals_.push_back(channels_[who]->get_signal()); + available_GPS_L5_signals_.remove(gs); + available_GPS_L5_signals_.push_back(gs); break; case evGAL_1B: - available_GAL_1B_signals_.push_back(channels_[who]->get_signal()); + available_GAL_1B_signals_.remove(gs); + available_GAL_1B_signals_.push_back(gs); break; case evGAL_5X: - available_GAL_5X_signals_.push_back(channels_[who]->get_signal()); + available_GAL_5X_signals_.remove(gs); + available_GAL_5X_signals_.push_back(gs); break; case evGLO_1G: - available_GLO_1G_signals_.push_back(channels_[who]->get_signal()); + available_GLO_1G_signals_.remove(gs); + available_GLO_1G_signals_.push_back(gs); break; case evGLO_2G: - available_GLO_2G_signals_.push_back(channels_[who]->get_signal()); + available_GLO_2G_signals_.remove(gs); + available_GLO_2G_signals_.push_back(gs); break; default: @@ -1018,7 +1046,162 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) } } break; + case 10: //request stanby mode + LOG(INFO) << "TC request stanby mode"; + for (size_t n = 0; n < channels_.size(); n++) + { + if (channels_state_[n] == 1 or channels_state_[n] == 2) //channel in acquisition or in tracking + { + //recover the satellite assigned + Gnss_Signal gs = channels_[n]->get_signal(); + switch (mapStringValues_[gs.get_signal_str()]) + { + case evGPS_1C: + available_GPS_1C_signals_.remove(gs); + available_GPS_1C_signals_.push_back(gs); + break; + + case evGPS_2S: + available_GPS_2S_signals_.remove(gs); + available_GPS_2S_signals_.push_back(gs); + break; + + case evGPS_L5: + available_GPS_L5_signals_.remove(gs); + available_GPS_L5_signals_.push_back(gs); + break; + + case evGAL_1B: + available_GAL_1B_signals_.remove(gs); + available_GAL_1B_signals_.push_back(gs); + break; + + case evGAL_5X: + available_GAL_5X_signals_.remove(gs); + available_GAL_5X_signals_.push_back(gs); + break; + + case evGLO_1G: + available_GLO_1G_signals_.remove(gs); + available_GLO_1G_signals_.push_back(gs); + break; + + case evGLO_2G: + available_GLO_2G_signals_.remove(gs); + available_GLO_2G_signals_.push_back(gs); + break; + + default: + LOG(ERROR) << "This should not happen :-("; + break; + } + channels_[n]->stop_channel(); //stop the acquisition or tracking operation + channels_state_[n] = 0; + } + } + acq_channels_count_ = 0; //all channels are in stanby now + break; + case 11: //request coldstart mode + LOG(INFO) << "TC request coldstart"; + //todo: delete all ephemeris and almanac information from maps (also the PVT map queue) + //todo: reorder the satellite queues to the receiver default startup order. + //This is required to allow repeatability. Otherwise the satellite search order will depend on the last tracked satellites + + //start again the satellite acquisitions + for (unsigned int i = 0; i < channels_count_; i++) + { + unsigned int ch_index = (who + i + 1) % channels_count_; + unsigned int sat_ = 0; + try + { + sat_ = configuration_->property("Channel" + std::to_string(ch_index) + ".satellite", 0); + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } + if ((acq_channels_count_ < max_acq_channels_) && (channels_state_[ch_index] == 0)) + { + channels_state_[ch_index] = 1; + if (sat_ == 0) + { + channels_[ch_index]->set_signal(search_next_signal(channels_[ch_index]->get_signal().get_signal_str(), true)); + } + 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(); + channels_[ch_index]->start_acquisition(); + } + DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index]; + } + break; + case 12: //request hotstart mode + LOG(INFO) << "TC request hotstart"; + //todo: call here the function that computes the set of visible satellites and its elevation + //for the date and time specified by the hotstart command and the last available PVT + //todo: reorder the satellite queue to acquire first those visible satellites + //start again the satellite acquisitions + for (unsigned int i = 0; i < channels_count_; i++) + { + unsigned int ch_index = (who + i + 1) % channels_count_; + unsigned int sat_ = 0; + try + { + sat_ = configuration_->property("Channel" + std::to_string(ch_index) + ".satellite", 0); + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } + if ((acq_channels_count_ < max_acq_channels_) && (channels_state_[ch_index] == 0)) + { + channels_state_[ch_index] = 1; + if (sat_ == 0) + { + channels_[ch_index]->set_signal(search_next_signal(channels_[ch_index]->get_signal().get_signal_str(), true)); + } + 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(); + channels_[ch_index]->start_acquisition(); + } + DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index]; + } + break; + case 13: //request warmstart mode + LOG(INFO) << "TC request warmstart"; + //todo: delete all ephemeris and almanac information from maps (also the PVT map queue) + //todo: load the ephemeris and the almanac from XML files (receiver assistance) + //todo: call here the function that computes the set of visible satellites and its elevation + //for the date and time specified by the warmstart command and the assisted position + //todo: reorder the satellite queue to acquire first those visible satellites + + //start again the satellite acquisitions + for (unsigned int i = 0; i < channels_count_; i++) + { + unsigned int ch_index = (who + i + 1) % channels_count_; + unsigned int sat_ = 0; + try + { + sat_ = configuration_->property("Channel" + std::to_string(ch_index) + ".satellite", 0); + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } + if ((acq_channels_count_ < max_acq_channels_) && (channels_state_[ch_index] == 0)) + { + channels_state_[ch_index] = 1; + if (sat_ == 0) + { + channels_[ch_index]->set_signal(search_next_signal(channels_[ch_index]->get_signal().get_signal_str(), true)); + } + 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(); + channels_[ch_index]->start_acquisition(); + } + DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index]; + } + break; default: break; } diff --git a/src/core/receiver/tcp_cmd_interface.cc b/src/core/receiver/tcp_cmd_interface.cc new file mode 100644 index 000000000..175d96859 --- /dev/null +++ b/src/core/receiver/tcp_cmd_interface.cc @@ -0,0 +1,273 @@ +/*! + * \file tcp_cmd_interface.cc + * + * \brief Class that implements a TCP telecontrol command line interface + * for GNSS-SDR + * \author Javier Arribas jarribas (at) cttc.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "tcp_cmd_interface.h" +#include "control_message_factory.h" +#include + + +std::string TcpCmdInterface::reset(const std::vector &commandLine) +{ + std::string response; + std::unique_ptr cmf(new ControlMessageFactory()); + if (control_queue_ != nullptr) + { + control_queue_->handle(cmf->GetQueueMessage(200, 1)); //send the restart message (who=200,what=1) + response = "OK\n"; + } + else + { + response = "ERROR\n"; + } + + return response; +} + +std::string TcpCmdInterface::standby(const std::vector &commandLine) +{ + std::string response; + std::unique_ptr cmf(new ControlMessageFactory()); + if (control_queue_ != nullptr) + { + control_queue_->handle(cmf->GetQueueMessage(300, 10)); //send the standby message (who=300,what=10) + response = "OK\n"; + } + else + { + response = "ERROR\n"; + } + return response; +} + +std::string TcpCmdInterface::status(const std::vector &commandLine) +{ + std::string response; + //todo: implement the receiver status report + response = "Not implemented\n"; + return response; +} + +std::string TcpCmdInterface::hotstart(const std::vector &commandLine) +{ + std::string response; + //todo: read and parse the command line parameter: dd/mm/yyyy HH:MM:SS + //todo: store it in a member variable + std::unique_ptr cmf(new ControlMessageFactory()); + if (control_queue_ != nullptr) + { + control_queue_->handle(cmf->GetQueueMessage(300, 12)); //send the standby message (who=300,what=12) + response = "OK\n"; + } + else + { + response = "ERROR\n"; + } + return response; +} + +std::string TcpCmdInterface::warmstart(const std::vector &commandLine) +{ + std::string response; + //todo: read and parse the command line parameter: dd/mm/yyyy HH:MM:SS + //todo: store it in a member variable + std::unique_ptr cmf(new ControlMessageFactory()); + if (control_queue_ != nullptr) + { + control_queue_->handle(cmf->GetQueueMessage(300, 13)); //send the standby message (who=300,what=13) + response = "OK\n"; + } + else + { + response = "ERROR\n"; + } + return response; +} + + +std::string TcpCmdInterface::coldstart(const std::vector &commandLine) +{ + std::string response; + std::unique_ptr cmf(new ControlMessageFactory()); + if (control_queue_ != nullptr) + { + control_queue_->handle(cmf->GetQueueMessage(300, 11)); //send the standby message (who=300,what=11) + response = "OK\n"; + } + else + { + response = "ERROR\n"; + } + return response; +} + +std::string TcpCmdInterface::set_ch_satellite(const std::vector &commandLine) +{ + std::string response; + //todo: implement the set satellite command + response = "Not implemented\n"; + return response; +} + + +void TcpCmdInterface::register_functions() +{ + functions["status"] = std::bind(&TcpCmdInterface::status, this, std::placeholders::_1); + functions["standby"] = std::bind(&TcpCmdInterface::standby, this, std::placeholders::_1); + functions["reset"] = std::bind(&TcpCmdInterface::reset, this, std::placeholders::_1); + functions["hotstart"] = std::bind(&TcpCmdInterface::hotstart, this, std::placeholders::_1); + functions["warmstart"] = std::bind(&TcpCmdInterface::warmstart, this, std::placeholders::_1); + functions["coldstart"] = std::bind(&TcpCmdInterface::coldstart, this, std::placeholders::_1); + functions["set_ch_satellite"] = std::bind(&TcpCmdInterface::set_ch_satellite, this, std::placeholders::_1); +} + + +TcpCmdInterface::TcpCmdInterface() +{ + register_functions(); + keep_running_ = true; + control_queue_ = nullptr; +} + + +void TcpCmdInterface::set_msg_queue(gr::msg_queue::sptr control_queue) +{ + control_queue_ = control_queue; +} +void TcpCmdInterface::run_cmd_server(int tcp_port) +{ + // Get the port from the parameters + uint16_t port = tcp_port; + + // Error to not throw exception + boost::system::error_code not_throw; + + // Socket and acceptor + boost::asio::io_service service; + try + { + boost::asio::ip::tcp::acceptor acceptor(service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)); + + while (keep_running_) + { + try + { + std::cout << "TcpCmdInterface: Telecommand TCP interface listening on port " << tcp_port << std::endl; + + boost::asio::ip::tcp::socket socket(service); + acceptor.accept(socket, not_throw); + if (not_throw) + { + std::cout << "TcpCmdInterface: Error when binding the port in the socket" << std::endl; + continue; + } + + // Read a message + boost::system::error_code error = boost::asio::error::eof; + do + { + std::string response; + boost::asio::streambuf b; + boost::asio::read_until(socket, b, '\n', error); + std::istream is(&b); + std::string line; + std::getline(is, line); + std::istringstream iss(line); + std::vector cmd_vector(std::istream_iterator{iss}, + std::istream_iterator()); + + if (cmd_vector.size() > 0) + { + try + { + if (cmd_vector.at(0).compare("exit") == 0) + { + error = boost::asio::error::eof; + //send cmd response + socket.write_some(boost::asio::buffer("OK\n"), not_throw); + } + else + { + response = functions[cmd_vector.at(0)](cmd_vector); + } + } + catch (const std::exception &ex) + { + response = "ERROR: command execution error: " + std::string(ex.what()) + "\n"; + } + } + else + { + response = "ERROR: empty command\n"; + } + + //send cmd response + socket.write_some(boost::asio::buffer(response), not_throw); + if (not_throw) + { + std::cout << "Error sending(" << not_throw.value() << "): " << not_throw.message() << std::endl; + break; + } + } + while (error != boost::asio::error::eof); + + if (error == boost::asio::error::eof) + { + std::cout << "TcpCmdInterface: EOF detected\n"; + } + else + { + std::cout << "TcpCmdInterface unexpected error: " << error << std::endl; + } + + // Close socket + socket.close(); + } + catch (const boost::exception &e) + { + std::cout << "TcpCmdInterface: Boost exception " << std::endl; + } + catch (const std::exception &ex) + { + std::cout << "TcpCmdInterface: Exception " << ex.what() << std::endl; + } + } + } + catch (const boost::exception &e) + { + std::cout << "TCP Command Interface exception: address already in use" << std::endl; + } +} + + +TcpCmdInterface::~TcpCmdInterface() +{ + // TODO Auto-generated destructor stub +} diff --git a/src/core/receiver/tcp_cmd_interface.h b/src/core/receiver/tcp_cmd_interface.h new file mode 100644 index 000000000..6071e32bd --- /dev/null +++ b/src/core/receiver/tcp_cmd_interface.h @@ -0,0 +1,73 @@ +/*! + * \file tcp_cmd_interface.h + * + * \brief Class that implements a TCP telecontrol command line interface + * for GNSS-SDR + * \author Javier Arribas jarribas (at) cttc.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ +#ifndef GNSS_SDR_TCPCMDINTERFACE_H_ +#define GNSS_SDR_TCPCMDINTERFACE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class TcpCmdInterface +{ +public: + TcpCmdInterface(); + virtual ~TcpCmdInterface(); + void run_cmd_server(int tcp_port); + void set_msg_queue(gr::msg_queue::sptr control_queue); + + +private: + std::unordered_map &)>> + functions; + std::string status(const std::vector &commandLine); + std::string reset(const std::vector &commandLine); + std::string standby(const std::vector &commandLine); + std::string hotstart(const std::vector &commandLine); + std::string warmstart(const std::vector &commandLine); + std::string coldstart(const std::vector &commandLine); + std::string set_ch_satellite(const std::vector &commandLine); + + void register_functions(); + + gr::msg_queue::sptr control_queue_; + bool keep_running_; +}; + +#endif /* GNSS_SDR_TCPCMDINTERFACE_H_ */ diff --git a/src/core/system_parameters/CMakeLists.txt b/src/core/system_parameters/CMakeLists.txt index ec8880116..9561d7c72 100644 --- a/src/core/system_parameters/CMakeLists.txt +++ b/src/core/system_parameters/CMakeLists.txt @@ -30,6 +30,7 @@ set(SYSTEM_PARAMETERS_SOURCES galileo_utc_model.cc galileo_ephemeris.cc galileo_almanac.cc + galileo_almanac_helper.cc galileo_iono.cc galileo_navigation_message.cc sbas_ephemeris.cc @@ -59,6 +60,7 @@ set(SYSTEM_PARAMETERS_HEADERS galileo_utc_model.h galileo_ephemeris.h galileo_almanac.h + galileo_almanac_helper.h galileo_iono.h galileo_navigation_message.h sbas_ephemeris.h @@ -83,7 +85,7 @@ set(SYSTEM_PARAMETERS_HEADERS GPS_L1_CA.h GPS_L2C.h GPS_L5.h - MATH_CONSTANTS.h + MATH_CONSTANTS.h ) diff --git a/src/core/system_parameters/galileo_almanac.cc b/src/core/system_parameters/galileo_almanac.cc index 805e8b6e3..27931f8b0 100644 --- a/src/core/system_parameters/galileo_almanac.cc +++ b/src/core/system_parameters/galileo_almanac.cc @@ -1,7 +1,7 @@ /*! * \file galileo_almanac.cc - * \brief Implementation of a Galileo ALMANAC storage - * \author Javier Arribas, 2013. jarribas(at)cttc.es + * \brief Interface of a Galileo ALMANAC storage + * \author Carles Fernandez, 2018. cfernandez(at)cttc.cat * * ------------------------------------------------------------------------- * @@ -30,66 +30,23 @@ #include "galileo_almanac.h" + Galileo_Almanac::Galileo_Almanac() { - // Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number - IOD_a_7 = 0; - WN_a_7 = 0.0; - t0a_7 = 0.0; - SVID1_7 = 0; - DELTA_A_7 = 0.0; - e_7 = 0.0; - omega_7 = 0.0; - delta_i_7 = 0.0; - Omega0_7 = 0.0; - Omega_dot_7 = 0.0; - M0_7 = 0.0; - - // Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2) - IOD_a_8 = 0; - af0_8 = 0.0; - af1_8 = 0.0; - E5b_HS_8 = 0.0; - E1B_HS_8 = 0.0; - E5a_HS_8 = 0.0; - SVID2_8 = 0; - DELTA_A_8 = 0.0; - e_8 = 0.0; - omega_8 = 0.0; - delta_i_8 = 0.0; - Omega0_8 = 0.0; - Omega_dot_8 = 0.0; - - // Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2) - IOD_a_9 = 0; - WN_a_9 = 0.0; - t0a_9 = 0.0; - M0_9 = 0.0; - af0_9 = 0.0; - af1_9 = 0.0; - E5b_HS_9 = 0.0; - E1B_HS_9 = 0.0; - E5a_HS_9 = 0.0; - SVID3_9 = 0; - DELTA_A_9 = 0.0; - e_9 = 0.0; - omega_9 = 0.0; - delta_i_9 = 0.0; - - // Word type 10: Almanac for SVID3 (2/2) - IOD_a_10 = 0; - Omega0_10 = 0.0; - Omega_dot_10 = 0.0; - M0_10 = 0.0; - af0_10 = 0.0; - af1_10 = 0.0; - E5b_HS_10 = 0.0; - E1B_HS_10 = 0.0; - E5a_HS_10 = 0.0; - - // GPS to Galileo GST conversion parameters - A_0G_10 = 0.0; - A_1G_10 = 0.0; - t_0G_10 = 0.0; - WN_0G_10 = 0.0; + i_satellite_PRN = 0U; + d_Toa = 0.0; + d_WNa = 0.0; + d_IODa = 0.0; + d_Delta_i = 0.0; + d_M_0 = 0.0; + d_e_eccentricity = 0.0; + d_Delta_sqrt_A = 0.0; + d_OMEGA0 = 0.0; + d_OMEGA = 0.0; + d_OMEGA_DOT = 0.0; + d_A_f0 = 0.0; + d_A_f1 = 0.0; + E5b_HS = 0.0; + E1B_HS = 0.0; + E5a_HS = 0.0; } diff --git a/src/core/system_parameters/galileo_almanac.h b/src/core/system_parameters/galileo_almanac.h index c8fb51e70..1529355ae 100644 --- a/src/core/system_parameters/galileo_almanac.h +++ b/src/core/system_parameters/galileo_almanac.h @@ -1,8 +1,8 @@ /*! * \file galileo_almanac.h * \brief Interface of a Galileo ALMANAC storage - * \author Javier Arribas, 2013. jarribas(at)cttc.es - * \author Mara Branzanti 2013. mara.branzanti(at)gmail.com + * \author Carles Fernandez, 2018. cfernandez(at)cttc.cat + * * ------------------------------------------------------------------------- * * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) @@ -28,81 +28,65 @@ * ------------------------------------------------------------------------- */ + #ifndef GNSS_SDR_GALILEO_ALMANAC_H_ #define GNSS_SDR_GALILEO_ALMANAC_H_ +#include #include /*! - * \brief This class is a storage for the GALILEO ALMANAC data as described in GALILEO ICD - * - * See https://www.gsc-europa.eu/system/files/galileo_documents/Galileo_OS_SIS_ICD.pdf paragraph 5.1.10 + * \brief This class is a storage for the Galileo SV ALMANAC data */ class Galileo_Almanac { public: - // Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number - int32_t IOD_a_7; - double WN_a_7; - double t0a_7; - int32_t SVID1_7; - double DELTA_A_7; - double e_7; - double omega_7; - double delta_i_7; - double Omega0_7; - double Omega_dot_7; - double M0_7; + uint32_t i_satellite_PRN; //!< SV PRN NUMBER + double d_Toa; + double d_WNa; + double d_IODa; + double d_Delta_i; + double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles] + double d_e_eccentricity; //!< Eccentricity [dimensionless] + double d_Delta_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)] + double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] + double d_OMEGA; //!< Argument of Perigee [semi-cicles] + double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s] + double d_A_f0; //!< Coefficient 0 of code phase offset model [s] + double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s] + double E5b_HS; + double E1B_HS; + double E5a_HS; - // Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2) - int32_t IOD_a_8; - double af0_8; - double af1_8; - double E5b_HS_8; - double E1B_HS_8; - double E5a_HS_8; - int32_t SVID2_8; - double DELTA_A_8; - double e_8; - double omega_8; - double delta_i_8; - double Omega0_8; - double Omega_dot_8; + /*! + * Default constructor + */ + Galileo_Almanac(); - // Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2) - int32_t IOD_a_9; - double WN_a_9; - double t0a_9; - double M0_9; - double af0_9; - double af1_9; - double E5b_HS_9; - double E1B_HS_9; - double E5a_HS_9; - int32_t SVID3_9; - double DELTA_A_9; - double e_9; - double omega_9; - double delta_i_9; + template - // Word type 10: Almanac for SVID3 (2/2) - int32_t IOD_a_10; - double Omega0_10; - double Omega_dot_10; - double M0_10; - double af0_10; - double af1_10; - double E5b_HS_10; - double E1B_HS_10; - double E5a_HS_10; - - // GPS to Galileo GST conversion parameters - double A_0G_10; - double A_1G_10; - double t_0G_10; - double WN_0G_10; - - Galileo_Almanac(); //!< Default constructor + void serialize(Archive& ar, const unsigned int version) + { + if (version) + { + }; + ar& BOOST_SERIALIZATION_NVP(i_satellite_PRN); + ar& BOOST_SERIALIZATION_NVP(d_Toa); + ar& BOOST_SERIALIZATION_NVP(d_WNa); + ar& BOOST_SERIALIZATION_NVP(d_IODa); + ar& BOOST_SERIALIZATION_NVP(d_Delta_i); + ar& BOOST_SERIALIZATION_NVP(d_M_0); + ar& BOOST_SERIALIZATION_NVP(d_e_eccentricity); + ar& BOOST_SERIALIZATION_NVP(d_Delta_sqrt_A); + ar& BOOST_SERIALIZATION_NVP(d_OMEGA0); + ar& BOOST_SERIALIZATION_NVP(d_OMEGA); + ar& BOOST_SERIALIZATION_NVP(d_OMEGA_DOT); + ar& BOOST_SERIALIZATION_NVP(d_A_f0); + ar& BOOST_SERIALIZATION_NVP(d_A_f1); + ar& BOOST_SERIALIZATION_NVP(E5b_HS); + ar& BOOST_SERIALIZATION_NVP(E1B_HS); + ar& BOOST_SERIALIZATION_NVP(E5a_HS); + } }; #endif diff --git a/src/core/system_parameters/galileo_almanac_helper.cc b/src/core/system_parameters/galileo_almanac_helper.cc new file mode 100644 index 000000000..738ecc8dc --- /dev/null +++ b/src/core/system_parameters/galileo_almanac_helper.cc @@ -0,0 +1,157 @@ +/*! + * \file galileo_almanac_helper.cc + * \brief Implementation of a Galileo ALMANAC storage helper + * \author Javier Arribas, 2013. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "galileo_almanac_helper.h" + +Galileo_Almanac_Helper::Galileo_Almanac_Helper() +{ + // Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number + IOD_a_7 = 0; + WN_a_7 = 0.0; + t0a_7 = 0.0; + SVID1_7 = 0; + DELTA_A_7 = 0.0; + e_7 = 0.0; + omega_7 = 0.0; + delta_i_7 = 0.0; + Omega0_7 = 0.0; + Omega_dot_7 = 0.0; + M0_7 = 0.0; + + // Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2) + IOD_a_8 = 0; + af0_8 = 0.0; + af1_8 = 0.0; + E5b_HS_8 = 0.0; + E1B_HS_8 = 0.0; + E5a_HS_8 = 0.0; + SVID2_8 = 0; + DELTA_A_8 = 0.0; + e_8 = 0.0; + omega_8 = 0.0; + delta_i_8 = 0.0; + Omega0_8 = 0.0; + Omega_dot_8 = 0.0; + + // Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2) + IOD_a_9 = 0; + WN_a_9 = 0.0; + t0a_9 = 0.0; + M0_9 = 0.0; + af0_9 = 0.0; + af1_9 = 0.0; + E5b_HS_9 = 0.0; + E1B_HS_9 = 0.0; + E5a_HS_9 = 0.0; + SVID3_9 = 0; + DELTA_A_9 = 0.0; + e_9 = 0.0; + omega_9 = 0.0; + delta_i_9 = 0.0; + + // Word type 10: Almanac for SVID3 (2/2) + IOD_a_10 = 0; + Omega0_10 = 0.0; + Omega_dot_10 = 0.0; + M0_10 = 0.0; + af0_10 = 0.0; + af1_10 = 0.0; + E5b_HS_10 = 0.0; + E1B_HS_10 = 0.0; + E5a_HS_10 = 0.0; +} + +Galileo_Almanac Galileo_Almanac_Helper::get_almanac(int i) +{ + Galileo_Almanac galileo_almanac; + switch (i) + { + case 1: + galileo_almanac.i_satellite_PRN = this->SVID1_7; + galileo_almanac.d_Toa = this->t0a_7; + galileo_almanac.d_WNa = this->WN_a_7; + galileo_almanac.d_IODa = this->IOD_a_7; + galileo_almanac.d_Delta_i = this->delta_i_7; + galileo_almanac.d_M_0 = this->M0_7; + galileo_almanac.d_e_eccentricity = this->e_7; + galileo_almanac.d_Delta_sqrt_A = this->DELTA_A_7; + galileo_almanac.d_OMEGA0 = this->Omega0_7; + galileo_almanac.d_OMEGA = this->omega_7; + galileo_almanac.d_OMEGA_DOT = this->Omega_dot_7; + galileo_almanac.d_A_f0 = this->af0_8; + galileo_almanac.d_A_f1 = this->af1_8; + galileo_almanac.E5b_HS = this->E5b_HS_8; + galileo_almanac.E1B_HS = this->E1B_HS_8; + galileo_almanac.E5a_HS = this->E5a_HS_8; + break; + + case 2: + galileo_almanac.i_satellite_PRN = this->SVID2_8; + galileo_almanac.d_Toa = this->t0a_9; + galileo_almanac.d_WNa = this->WN_a_9; + galileo_almanac.d_IODa = this->IOD_a_9; + galileo_almanac.d_Delta_i = this->delta_i_8; + galileo_almanac.d_M_0 = this->M0_9; + galileo_almanac.d_e_eccentricity = this->e_8; + galileo_almanac.d_Delta_sqrt_A = this->DELTA_A_8; + galileo_almanac.d_OMEGA0 = this->Omega0_8; + galileo_almanac.d_OMEGA = this->omega_8; + galileo_almanac.d_OMEGA_DOT = this->Omega_dot_8; + galileo_almanac.d_A_f0 = this->af0_9; + galileo_almanac.d_A_f1 = this->af1_9; + galileo_almanac.E5b_HS = this->E5b_HS_9; + galileo_almanac.E1B_HS = this->E1B_HS_9; + galileo_almanac.E5a_HS = this->E5a_HS_9; + break; + + case 3: + galileo_almanac.i_satellite_PRN = this->SVID3_9; + galileo_almanac.d_Toa = this->t0a_9; + galileo_almanac.d_WNa = this->WN_a_9; + galileo_almanac.d_IODa = this->IOD_a_10; + galileo_almanac.d_Delta_i = this->delta_i_9; + galileo_almanac.d_M_0 = this->M0_10; + galileo_almanac.d_e_eccentricity = this->e_9; + galileo_almanac.d_Delta_sqrt_A = this->DELTA_A_9; + galileo_almanac.d_OMEGA0 = this->Omega0_10; + galileo_almanac.d_OMEGA = this->omega_9; + galileo_almanac.d_OMEGA_DOT = this->Omega_dot_10; + galileo_almanac.d_A_f0 = this->af0_10; + galileo_almanac.d_A_f1 = this->af1_10; + galileo_almanac.E5b_HS = this->E5b_HS_10; + galileo_almanac.E1B_HS = this->E1B_HS_10; + galileo_almanac.E5a_HS = this->E5a_HS_10; + break; + + default: + break; + } + return galileo_almanac; +} diff --git a/src/core/system_parameters/galileo_almanac_helper.h b/src/core/system_parameters/galileo_almanac_helper.h new file mode 100644 index 000000000..c0541a214 --- /dev/null +++ b/src/core/system_parameters/galileo_almanac_helper.h @@ -0,0 +1,104 @@ +/*! + * \file galileo_almanac_helper.h + * \brief Interface of a Galileo ALMANAC storage helper + * \author Javier Arribas, 2013. jarribas(at)cttc.es + * \author Mara Branzanti 2013. mara.branzanti(at)gmail.com + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GALILEO_ALMANAC_HELPER_H_ +#define GNSS_SDR_GALILEO_ALMANAC_HELPER_H_ + +#include "galileo_almanac.h" +#include + +/*! + * \brief This class is a storage for the GALILEO ALMANAC data as described in GALILEO ICD + * + * See https://www.gsc-europa.eu/system/files/galileo_documents/Galileo_OS_SIS_ICD.pdf paragraph 5.1.10 + */ +class Galileo_Almanac_Helper +{ +public: + // Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number + int32_t IOD_a_7; + double WN_a_7; + double t0a_7; + int32_t SVID1_7; + double DELTA_A_7; + double e_7; + double omega_7; + double delta_i_7; + double Omega0_7; + double Omega_dot_7; + double M0_7; + + // Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2) + int32_t IOD_a_8; + double af0_8; + double af1_8; + double E5b_HS_8; + double E1B_HS_8; + double E5a_HS_8; + int32_t SVID2_8; + double DELTA_A_8; + double e_8; + double omega_8; + double delta_i_8; + double Omega0_8; + double Omega_dot_8; + + // Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2) + int32_t IOD_a_9; + double WN_a_9; + double t0a_9; + double M0_9; + double af0_9; + double af1_9; + double E5b_HS_9; + double E1B_HS_9; + double E5a_HS_9; + int32_t SVID3_9; + double DELTA_A_9; + double e_9; + double omega_9; + double delta_i_9; + + // Word type 10: Almanac for SVID3 (2/2) + int32_t IOD_a_10; + double Omega0_10; + double Omega_dot_10; + double M0_10; + double af0_10; + double af1_10; + double E5b_HS_10; + double E1B_HS_10; + double E5a_HS_10; + + Galileo_Almanac_Helper(); //!< Default constructor + Galileo_Almanac get_almanac(int i); +}; + +#endif diff --git a/src/core/system_parameters/galileo_fnav_message.cc b/src/core/system_parameters/galileo_fnav_message.cc index cc1509b4c..42a4a7c1b 100644 --- a/src/core/system_parameters/galileo_fnav_message.cc +++ b/src/core/system_parameters/galileo_fnav_message.cc @@ -630,9 +630,9 @@ Galileo_Utc_Model Galileo_Fnav_Message::get_utc_model() } -Galileo_Almanac Galileo_Fnav_Message::get_almanac() +Galileo_Almanac_Helper Galileo_Fnav_Message::get_almanac() { - Galileo_Almanac almanac; + Galileo_Almanac_Helper almanac; // FNAV equivalent of INAV Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number almanac.IOD_a_7 = FNAV_IODa_5; almanac.WN_a_7 = FNAV_WNa_5; diff --git a/src/core/system_parameters/galileo_fnav_message.h b/src/core/system_parameters/galileo_fnav_message.h index 3cb6e76a5..2a16578be 100644 --- a/src/core/system_parameters/galileo_fnav_message.h +++ b/src/core/system_parameters/galileo_fnav_message.h @@ -40,7 +40,7 @@ #include "galileo_ephemeris.h" #include "galileo_iono.h" -#include "galileo_almanac.h" +#include "galileo_almanac_helper.h" #include "galileo_utc_model.h" #include "Galileo_E5a.h" #include @@ -66,7 +66,7 @@ public: Galileo_Ephemeris get_ephemeris(); Galileo_Iono get_iono(); Galileo_Utc_Model get_utc_model(); - Galileo_Almanac get_almanac(); + Galileo_Almanac_Helper get_almanac(); Galileo_Fnav_Message(); diff --git a/src/core/system_parameters/galileo_iono.h b/src/core/system_parameters/galileo_iono.h index cc8af7392..90c861c12 100644 --- a/src/core/system_parameters/galileo_iono.h +++ b/src/core/system_parameters/galileo_iono.h @@ -32,6 +32,7 @@ #ifndef GNSS_SDR_GALILEO_IONO_H_ #define GNSS_SDR_GALILEO_IONO_H_ +#include /*! * \brief This class is a storage for the GALILEO IONOSPHERIC data as described in Galileo ICD paragraph 5.1.6 @@ -61,6 +62,30 @@ public: * Default constructor */ Galileo_Iono(); + + template + + /*! + * \brief Serialize is a boost standard method to be called by the boost XML serialization. + Here is used to save the iono data on disk file. + */ + inline void serialize(Archive& archive, const unsigned int version) + { + using boost::serialization::make_nvp; + if (version) + { + }; + archive& make_nvp("ai0_5", ai0_5); + archive& make_nvp("ai1_5", ai1_5); + archive& make_nvp("ai2_5", ai2_5); + archive& make_nvp("Region1_flag_5", Region1_flag_5); + archive& make_nvp("Region2_flag_5", Region2_flag_5); + archive& make_nvp("Region3_flag_5", Region3_flag_5); + archive& make_nvp("Region4_flag_5", Region4_flag_5); + archive& make_nvp("Region5_flag_5", Region5_flag_5); + archive& make_nvp("TOW_5", TOW_5); + archive& make_nvp("WN_5", WN_5); + } }; #endif diff --git a/src/core/system_parameters/galileo_navigation_message.cc b/src/core/system_parameters/galileo_navigation_message.cc index 3fb375712..6d157aa46 100644 --- a/src/core/system_parameters/galileo_navigation_message.cc +++ b/src/core/system_parameters/galileo_navigation_message.cc @@ -578,13 +578,18 @@ Galileo_Utc_Model Galileo_Navigation_Message::get_utc_model() utc_model.DN_6 = DN_6; utc_model.Delta_tLSF_6 = Delta_tLSF_6; utc_model.flag_utc_model = flag_utc_model; + // GPS to Galileo GST conversion parameters + utc_model.A_0G_10 = A_0G_10; + utc_model.A_1G_10 = A_1G_10; + utc_model.t_0G_10 = t_0G_10; + utc_model.WN_0G_10 = WN_0G_10; return utc_model; } -Galileo_Almanac Galileo_Navigation_Message::get_almanac() +Galileo_Almanac_Helper Galileo_Navigation_Message::get_almanac() { - Galileo_Almanac almanac; + Galileo_Almanac_Helper almanac; // Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number almanac.IOD_a_7 = IOD_a_7; almanac.WN_a_7 = WN_a_7; @@ -637,12 +642,6 @@ Galileo_Almanac Galileo_Navigation_Message::get_almanac() almanac.E5b_HS_10 = E5b_HS_10; almanac.E1B_HS_10 = E1B_HS_10; - // GPS to Galileo GST conversion parameters - almanac.A_0G_10 = A_0G_10; - almanac.A_1G_10 = A_1G_10; - almanac.t_0G_10 = t_0G_10; - almanac.WN_0G_10 = WN_0G_10; - return almanac; } diff --git a/src/core/system_parameters/galileo_navigation_message.h b/src/core/system_parameters/galileo_navigation_message.h index 6b41312c4..d54e1b980 100644 --- a/src/core/system_parameters/galileo_navigation_message.h +++ b/src/core/system_parameters/galileo_navigation_message.h @@ -35,7 +35,7 @@ #include "galileo_ephemeris.h" #include "galileo_iono.h" -#include "galileo_almanac.h" +#include "galileo_almanac_helper.h" #include "galileo_utc_model.h" #include "Galileo_E1.h" #include @@ -290,9 +290,9 @@ public: Galileo_Utc_Model get_utc_model(); /* - * \brief Returns a Galileo_Almanac object filled with the latest navigation data received + * \brief Returns a Galileo_Almanac_Helper object filled with the latest navigation data received */ - Galileo_Almanac get_almanac(); + Galileo_Almanac_Helper get_almanac(); Galileo_Navigation_Message(); }; diff --git a/src/core/system_parameters/galileo_utc_model.cc b/src/core/system_parameters/galileo_utc_model.cc index 9464e51e9..660c20ca1 100644 --- a/src/core/system_parameters/galileo_utc_model.cc +++ b/src/core/system_parameters/galileo_utc_model.cc @@ -43,6 +43,11 @@ Galileo_Utc_Model::Galileo_Utc_Model() DN_6 = 0.0; Delta_tLSF_6 = 0.0; flag_utc_model = false; + // GPS to Galileo GST conversion parameters + A_0G_10 = 0.0; + A_1G_10 = 0.0; + t_0G_10 = 0.0; + WN_0G_10 = 0.0; } diff --git a/src/core/system_parameters/galileo_utc_model.h b/src/core/system_parameters/galileo_utc_model.h index cc72d78e2..174fb0754 100644 --- a/src/core/system_parameters/galileo_utc_model.h +++ b/src/core/system_parameters/galileo_utc_model.h @@ -33,6 +33,7 @@ #ifndef GNSS_SDR_GALILEO_UTC_MODEL_H_ #define GNSS_SDR_GALILEO_UTC_MODEL_H_ +#include /*! * \brief This class is a storage for the GALILEO UTC MODEL data as described in Galileo ICD @@ -52,12 +53,42 @@ public: double DN_6; double Delta_tLSF_6; bool flag_utc_model; + + // GPS to Galileo GST conversion parameters + double A_0G_10; + double A_1G_10; + double t_0G_10; + double WN_0G_10; + //double TOW_6; double GST_to_UTC_time(double t_e, int WN); //!< GST-UTC Conversion Algorithm and Parameters /*! * Default constructor */ Galileo_Utc_Model(); + + template + + /*! + * \brief Serialize is a boost standard method to be called by the boost XML serialization. + Here is used to save the UTC data on disk file. + */ + inline void serialize(Archive& archive, const unsigned int version) + { + using boost::serialization::make_nvp; + if (version) + { + }; + archive& make_nvp("A0_6", A0_6); + archive& make_nvp("A1_6", A1_6); + archive& make_nvp("Delta_tLS_6", Delta_tLS_6); + archive& make_nvp("t0t_6", t0t_6); + archive& make_nvp("WNot_6", WNot_6); + archive& make_nvp("WN_LSF_6", WN_LSF_6); + archive& make_nvp("DN_6", DN_6); + archive& make_nvp("Delta_tLSF_6", Delta_tLSF_6); + archive& make_nvp("flag_utc_model", flag_utc_model); + } }; #endif diff --git a/src/core/system_parameters/gps_almanac.cc b/src/core/system_parameters/gps_almanac.cc index acf7068b0..c2776dcce 100644 --- a/src/core/system_parameters/gps_almanac.cc +++ b/src/core/system_parameters/gps_almanac.cc @@ -37,6 +37,7 @@ Gps_Almanac::Gps_Almanac() i_satellite_PRN = 0U; d_Delta_i = 0.0; d_Toa = 0.0; + i_WNa = 0; d_M_0 = 0.0; d_e_eccentricity = 0.0; d_sqrt_A = 0.0; @@ -44,6 +45,7 @@ Gps_Almanac::Gps_Almanac() d_OMEGA = 0.0; d_OMEGA_DOT = 0.0; i_SV_health = 0; + i_AS_status = 0; d_A_f0 = 0.0; d_A_f1 = 0.0; } diff --git a/src/core/system_parameters/gps_almanac.h b/src/core/system_parameters/gps_almanac.h index 22bb79c4c..57288d3db 100644 --- a/src/core/system_parameters/gps_almanac.h +++ b/src/core/system_parameters/gps_almanac.h @@ -32,6 +32,7 @@ #ifndef GNSS_SDR_GPS_ALMANAC_H_ #define GNSS_SDR_GPS_ALMANAC_H_ +#include #include /*! @@ -43,22 +44,47 @@ class Gps_Almanac { public: uint32_t i_satellite_PRN; //!< SV PRN NUMBER - double d_Delta_i; - double d_Toa; //!< Almanac data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] - double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles] - double d_e_eccentricity; //!< Eccentricity [dimensionless] - double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)] - double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] - double d_OMEGA; //!< Argument of Perigee [semi-cicles] - double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s] - int32_t i_SV_health; // SV Health - double d_A_f0; //!< Coefficient 0 of code phase offset model [s] - double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s] + double d_Delta_i; //!< Inclination Angle at Reference Time (relative to i_0 = 0.30 semi-circles) + double d_Toa; //!< Almanac data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] + int32_t i_WNa; //!< Almanac week number + double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles] + double d_e_eccentricity; //!< Eccentricity [dimensionless] + double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)] + double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] + double d_OMEGA; //!< Argument of Perigee [semi-cicles] + double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s] + int32_t i_SV_health; //!< SV Health + int32_t i_AS_status; //!< Anti-Spoofing Flags and SV Configuration + double d_A_f0; //!< Coefficient 0 of code phase offset model [s] + double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s] /*! * Default constructor */ Gps_Almanac(); + + template + + void serialize(Archive& ar, const unsigned int version) + { + if (version) + { + }; + ar& BOOST_SERIALIZATION_NVP(i_satellite_PRN); + ar& BOOST_SERIALIZATION_NVP(d_Delta_i); + ar& BOOST_SERIALIZATION_NVP(d_Toa); + ar& BOOST_SERIALIZATION_NVP(i_WNa); + ar& BOOST_SERIALIZATION_NVP(d_M_0); + ar& BOOST_SERIALIZATION_NVP(d_e_eccentricity); + ar& BOOST_SERIALIZATION_NVP(d_sqrt_A); + ar& BOOST_SERIALIZATION_NVP(d_OMEGA0); + ar& BOOST_SERIALIZATION_NVP(d_OMEGA); + ar& BOOST_SERIALIZATION_NVP(d_OMEGA_DOT); + ar& BOOST_SERIALIZATION_NVP(i_SV_health); + ar& BOOST_SERIALIZATION_NVP(i_AS_status); + ar& BOOST_SERIALIZATION_NVP(d_A_f0); + ar& BOOST_SERIALIZATION_NVP(d_A_f1); + } }; #endif diff --git a/src/core/system_parameters/gps_cnav_navigation_message.cc b/src/core/system_parameters/gps_cnav_navigation_message.cc index 98d02d59d..642695469 100644 --- a/src/core/system_parameters/gps_cnav_navigation_message.cc +++ b/src/core/system_parameters/gps_cnav_navigation_message.cc @@ -391,5 +391,6 @@ bool Gps_CNAV_Navigation_Message::have_new_utc_model() // Check if we have a ne Gps_CNAV_Utc_Model Gps_CNAV_Navigation_Message::get_utc_model() { + utc_model_record.valid = true; return utc_model_record; } diff --git a/src/main/main.cc b/src/main/main.cc index d64f9bab6..9b3680115 100644 --- a/src/main/main.cc +++ b/src/main/main.cc @@ -135,9 +135,10 @@ int main(int argc, char** argv) std::chrono::time_point start, end; start = std::chrono::system_clock::now(); + int return_code; try { - control_thread->run(); + return_code = control_thread->run(); } catch (const boost::exception& e) { @@ -189,5 +190,5 @@ int main(int argc, char** argv) google::ShutDownCommandLineFlags(); std::cout << "GNSS-SDR program ended." << std::endl; - return 0; + return return_code; } diff --git a/src/tests/system-tests/libs/CMakeLists.txt b/src/tests/system-tests/libs/CMakeLists.txt index 0fe1d4440..4742e80fc 100644 --- a/src/tests/system-tests/libs/CMakeLists.txt +++ b/src/tests/system-tests/libs/CMakeLists.txt @@ -25,6 +25,7 @@ set(SYSTEM_TESTING_LIB_SOURCES include_directories( ${CMAKE_CURRENT_SOURCE_DIR} + ${Boost_INCLUDE_DIRS} ${GLOG_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS} ${MATIO_INCLUDE_DIRS} diff --git a/src/tests/system-tests/libs/position_test_flags.h b/src/tests/system-tests/libs/position_test_flags.h index e911fb892..cf33c344f 100644 --- a/src/tests/system-tests/libs/position_test_flags.h +++ b/src/tests/system-tests/libs/position_test_flags.h @@ -41,6 +41,11 @@ DEFINE_bool(use_pvt_solver_dump, false, "Use PVT solver binary dump or fall back DEFINE_bool(use_ref_motion_file, false, "Enable or disable the use of a reference file containing the true receiver position, velocity and acceleration."); DEFINE_int32(ref_motion_file_type, 1, "Type of reference motion file: 1- Spirent CSV motion file"); DEFINE_string(ref_motion_filename, std::string("motion.csv"), "Path and filename for the reference motion file"); -DEFINE_string(pvt_solver_dump_filename, std::string("PVT_pvt.dat"), "Path and filename for the PVT solver binary dump file"); - +DEFINE_string(pvt_solver_dump_filename, std::string("PVT.dat"), "Path and filename for the PVT solver binary dump file"); +DEFINE_double(static_2D_error_m, 2.0, "Static scenario 2D (East, North) positioning error threshold [meters]"); +DEFINE_double(static_3D_error_m, 5.0, "Static scenario 3D (East, North, Up) positioning error threshold [meters]"); +DEFINE_double(accuracy_CEP, 2.0, "Static scenario 2D (East, North) accuracy Circular Error Position (CEP) threshold [meters]"); +DEFINE_double(precision_SEP, 10.0, "Static scenario 3D (East, North, Up) precision Spherical Error Position (SEP) threshold [meters]"); +DEFINE_double(dynamic_3D_position_RMSE, 10.0, "Dynamic scenario 3D (ECEF) accuracy RMSE threshold [meters]"); +DEFINE_double(dynamic_3D_velocity_RMSE, 5.0, "Dynamic scenario 3D (ECEF) velocity accuracy RMSE threshold [meters/second]"); #endif diff --git a/src/tests/system-tests/position_test.cc b/src/tests/system-tests/position_test.cc index a306b30f1..1a4c5e780 100644 --- a/src/tests/system-tests/position_test.cc +++ b/src/tests/system-tests/position_test.cc @@ -56,6 +56,7 @@ #include #include #include +#include // For GPS NAVIGATION (L1) concurrent_queue global_gps_acq_assist_queue; @@ -69,6 +70,8 @@ public: int configure_receiver(); int run_receiver(); void check_results(); + bool save_mat_xy(std::vector& x, std::vector& y, std::string filename); + bool save_mat_x(std::vector& x, std::string filename); std::string config_filename_no_extension; private: @@ -190,7 +193,7 @@ int PositionSystemTest::configure_receiver() config->set_property("GNSS-SDR.SUPL_gps_acquisition_server", "supl.google.com"); config->set_property("GNSS-SDR.SUPL_gps_acquisition_port", std::to_string(7275)); config->set_property("GNSS-SDR.SUPL_MCC", std::to_string(244)); - config->set_property("GNSS-SDR.SUPL_MNS", std::to_string(5)); + config->set_property("GNSS-SDR.SUPL_MNC", std::to_string(5)); config->set_property("GNSS-SDR.SUPL_LAC", "0x59e2"); config->set_property("GNSS-SDR.SUPL_CI", "0x31b0"); @@ -356,6 +359,72 @@ int PositionSystemTest::run_receiver() } +bool PositionSystemTest::save_mat_xy(std::vector& x, std::vector& y, std::string filename) +{ + try + { + // WRITE MAT FILE + mat_t* matfp; + matvar_t* matvar; + filename.append(".mat"); + std::cout << "save_mat_xy write " << filename << std::endl; + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT5); + if (reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, x.size()}; + matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &x[0], 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &y[0], 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + else + { + std::cout << "save_mat_xy: error creating file" << std::endl; + } + Mat_Close(matfp); + return true; + } + catch (const std::exception& ex) + { + std::cout << "save_mat_xy: " << ex.what() << std::endl; + return false; + } +} + +bool PositionSystemTest::save_mat_x(std::vector& x, std::string filename) +{ + try + { + // WRITE MAT FILE + mat_t* matfp; + matvar_t* matvar; + filename.append(".mat"); + std::cout << "save_mat_x write " << filename << std::endl; + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT5); + if (reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, x.size()}; + matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &x[0], 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + else + { + std::cout << "save_mat_x: error creating file" << std::endl; + } + Mat_Close(matfp); + return true; + } + catch (const std::exception& ex) + { + std::cout << "save_mat_x: " << ex.what() << std::endl; + return false; + } +} + void PositionSystemTest::check_results() { arma::mat R_eb_e; //ECEF position (x,y,z) estimation in the Earth frame (Nx3) @@ -493,17 +562,36 @@ void PositionSystemTest::check_results() double sigma_N_2_precision = arma::var(R_eb_enu.row(1)); double sigma_U_2_precision = arma::var(R_eb_enu.row(2)); - arma::rowvec tmp_vec; - tmp_vec = R_eb_enu.row(0) - ref_r_enu(0); - double sigma_E_2_accuracy = sqrt(arma::sum(arma::square(tmp_vec)) / tmp_vec.n_cols); - tmp_vec = R_eb_enu.row(1) - ref_r_enu(1); - double sigma_N_2_accuracy = sqrt(arma::sum(arma::square(tmp_vec)) / tmp_vec.n_cols); - tmp_vec = R_eb_enu.row(2) - ref_r_enu(2); - double sigma_U_2_accuracy = sqrt(arma::sum(arma::square(tmp_vec)) / tmp_vec.n_cols); + arma::rowvec error_east_m; + error_east_m = R_eb_enu.row(0) - ref_r_enu(0); + double sigma_E_2_accuracy = arma::as_scalar(error_east_m * error_east_m.t()); + sigma_E_2_accuracy = sigma_E_2_accuracy / error_east_m.n_elem; - double mean__e = arma::mean(R_eb_enu.row(0)); - double mean__n = arma::mean(R_eb_enu.row(1)); - double mean__u = arma::mean(R_eb_enu.row(2)); + arma::rowvec error_north_m; + error_north_m = R_eb_enu.row(1) - ref_r_enu(1); + double sigma_N_2_accuracy = arma::as_scalar(error_north_m * error_north_m.t()); + sigma_N_2_accuracy = sigma_N_2_accuracy / error_north_m.n_elem; + + arma::rowvec error_up_m; + error_up_m = R_eb_enu.row(2) - ref_r_enu(2); + double sigma_U_2_accuracy = arma::as_scalar(error_up_m * error_up_m.t()); + sigma_U_2_accuracy = sigma_U_2_accuracy / error_up_m.n_elem; + + // arma::mat error_enu_mat = arma::zeros(3, error_east_m.n_elem); + // error_enu_mat.row(0) = error_east_m; + // error_enu_mat.row(1) = error_north_m; + // error_enu_mat.row(2) = error_up_m; + // + // arma::vec error_2D_m = arma::zeros(error_enu_mat.n_cols, 1); + // arma::vec error_3D_m = arma::zeros(error_enu_mat.n_cols, 1); + // for (uint64_t n = 0; n < error_enu_mat.n_cols; n++) + // { + // error_2D_m(n) = arma::norm(error_enu_mat.submat(0, n, 1, n)); + // error_3D_m(n) = arma::norm(error_enu_mat.col(n)); + // } + + double static_2D_error_m = sqrt(pow(arma::mean(error_east_m), 2.0) + pow(arma::mean(error_north_m), 2.0)); + double static_3D_error_m = sqrt(pow(arma::mean(error_east_m), 2.0) + pow(arma::mean(error_north_m), 2.0) + pow(arma::mean(error_up_m), 2.0)); std::stringstream stm; std::ofstream position_test_file; @@ -512,7 +600,7 @@ void PositionSystemTest::check_results() stm << "Configuration file: " << FLAGS_config_file_ptest << std::endl; } - stm << "---- ACCURACY ----" << std::endl; + stm << "---- STATIC ACCURACY ----" << std::endl; stm << "2DRMS = " << 2 * sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl; stm << "DRMS = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl; stm << "CEP = " << 0.62 * sqrt(sigma_N_2_accuracy) + 0.56 * sqrt(sigma_E_2_accuracy) << " [m]" << std::endl; @@ -520,11 +608,11 @@ void PositionSystemTest::check_results() stm << "90% SAS = " << 0.833 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; stm << "MRSE = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; stm << "SEP = " << 0.51 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; - stm << "Bias 2D = " << sqrt(std::pow(fabs(mean__e - ref_r_enu(0)), 2.0) + std::pow(fabs(mean__n - ref_r_enu(1)), 2.0)) << " [m]" << std::endl; - stm << "Bias 3D = " << sqrt(std::pow(fabs(mean__e - ref_r_enu(0)), 2.0) + std::pow(fabs(mean__n - ref_r_enu(1)), 2.0) + std::pow(fabs(mean__u - ref_r_enu(2)), 2.0)) << " [m]" << std::endl; + stm << "Static Bias 2D = " << static_2D_error_m << " [m]" << std::endl; + stm << "Static Bias 3D = " << static_3D_error_m << " [m]" << std::endl; stm << std::endl; - stm << "---- PRECISION ----" << std::endl; + stm << "---- STATIC PRECISION ----" << std::endl; stm << "2DRMS = " << 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl; stm << "DRMS = " << sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl; stm << "CEP = " << 0.62 * sqrt(sigma_N_2_precision) + 0.56 * sqrt(sigma_E_2_precision) << " [m]" << std::endl; @@ -543,8 +631,13 @@ void PositionSystemTest::check_results() } // Sanity Check + double accuracy_CEP = 0.62 * sqrt(sigma_N_2_accuracy) + 0.56 * sqrt(sigma_E_2_accuracy); double precision_SEP = 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision); - ASSERT_LT(precision_SEP, 1.0); + + EXPECT_LT(static_2D_error_m, FLAGS_static_2D_error_m); + EXPECT_LT(static_2D_error_m, FLAGS_static_2D_error_m); + ASSERT_LT(accuracy_CEP, FLAGS_accuracy_CEP); + ASSERT_LT(precision_SEP, FLAGS_precision_SEP); if (FLAGS_plot_position_test == true) { @@ -745,6 +838,11 @@ void PositionSystemTest::check_results() } } } + + //ERROR CHECK + //todo: reduce the error tolerance or enable the option to pass the error tolerance by parameter + EXPECT_LT(rmse_R_eb_e, FLAGS_dynamic_3D_position_RMSE); //3D RMS positioning error less than 10 meters + EXPECT_LT(rmse_V_eb_e, FLAGS_dynamic_3D_velocity_RMSE); //3D RMS speed error less than 5 meters/s (18 km/h) } } diff --git a/src/tests/system-tests/ttff.cc b/src/tests/system-tests/ttff.cc index 2d5dbba44..6bea0a570 100644 --- a/src/tests/system-tests/ttff.cc +++ b/src/tests/system-tests/ttff.cc @@ -135,7 +135,7 @@ void TtffTest::config_1() config->set_property("GNSS-SDR.SUPL_gps_acquisition_server", "supl.google.com"); config->set_property("GNSS-SDR.SUPL_gps_acquisition_port", std::to_string(7275)); config->set_property("GNSS-SDR.SUPL_MCC", std::to_string(244)); - config->set_property("GNSS-SDR.SUPL_MNS", std::to_string(5)); + config->set_property("GNSS-SDR.SUPL_MNC", std::to_string(5)); config->set_property("GNSS-SDR.SUPL_LAC", "0x59e2"); config->set_property("GNSS-SDR.SUPL_CI", "0x31b0"); diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt b/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt index 332f0e583..7d15075f2 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt +++ b/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt @@ -29,6 +29,7 @@ set(SIGNAL_PROCESSING_TESTING_LIB_SOURCES include_directories( ${CMAKE_CURRENT_SOURCE_DIR} + ${Boost_INCLUDE_DIRS} ${GLOG_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS} ${MATIO_INCLUDE_DIRS} diff --git a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc index d3f232a50..9422e144a 100644 --- a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc @@ -1836,9 +1836,9 @@ TEST_F(HybridObservablesTest, ValidationOfResults) if (FLAGS_duplicated_satellites_test) { //special test mode for duplicated satellites - std::vector prn_pairs; + std::vector prn_pairs; std::stringstream ss(FLAGS_duplicated_satellites_prns); - int i; + unsigned int i; while (ss >> i) { prn_pairs.push_back(i); diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc index a08b401c2..535cca464 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc @@ -157,7 +157,7 @@ void NmeaPrinterTest::conf() TEST_F(NmeaPrinterTest, PrintLine) { std::string filename("nmea_test.nmea"); - std::shared_ptr pvt_solution = std::make_shared(12, "filename", false, rtk); + std::shared_ptr pvt_solution = std::make_shared(12, "filename", false, false, rtk); boost::posix_time::ptime pt(boost::gregorian::date(1994, boost::date_time::Nov, 19), boost::posix_time::hours(22) + boost::posix_time::minutes(54) + boost::posix_time::seconds(46)); // example from http://aprs.gids.nl/nmea/#rmc @@ -168,8 +168,9 @@ TEST_F(NmeaPrinterTest, PrintLine) pvt_solution->set_valid_position(true); + bool flag_nmea_output_file = true; ASSERT_NO_THROW({ - std::shared_ptr nmea_printer = std::make_shared(filename, false, ""); + std::shared_ptr nmea_printer = std::make_shared(filename, flag_nmea_output_file, false, ""); nmea_printer->Print_Nmea_Line(pvt_solution, false); }) << "Failure printing NMEA messages."; @@ -195,7 +196,7 @@ TEST_F(NmeaPrinterTest, PrintLine) TEST_F(NmeaPrinterTest, PrintLineLessthan10min) { std::string filename("nmea_test.nmea"); - std::shared_ptr pvt_solution = std::make_shared(12, "filename", false, rtk); + std::shared_ptr pvt_solution = std::make_shared(12, "filename", false, false, rtk); boost::posix_time::ptime pt(boost::gregorian::date(1994, boost::date_time::Nov, 19), boost::posix_time::hours(22) + boost::posix_time::minutes(54) + boost::posix_time::seconds(46)); // example from http://aprs.gids.nl/nmea/#rmc @@ -206,8 +207,9 @@ TEST_F(NmeaPrinterTest, PrintLineLessthan10min) pvt_solution->set_valid_position(true); + bool flag_nmea_output_file = true; ASSERT_NO_THROW({ - std::shared_ptr nmea_printer = std::make_shared(filename, false, ""); + std::shared_ptr nmea_printer = std::make_shared(filename, flag_nmea_output_file, false, ""); nmea_printer->Print_Nmea_Line(pvt_solution, false); }) << "Failure printing NMEA messages."; diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc index edc349e91..4f648e0b7 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc @@ -39,9 +39,10 @@ TEST(RtcmPrinterTest, Instantiate) bool flag_rtcm_tty_port = false; std::string rtcm_dump_devname = "/dev/pts/4"; bool flag_rtcm_server = false; + bool rtcm_file_output_enabled = false; unsigned short rtcm_tcp_port = 2101; unsigned short rtcm_station_id = 1234; - std::unique_ptr RTCM_printer(new Rtcm_Printer(filename, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname)); + std::unique_ptr RTCM_printer(new Rtcm_Printer(filename, rtcm_file_output_enabled, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname)); } @@ -49,12 +50,13 @@ TEST(RtcmPrinterTest, Run) { std::string filename = "test.rtcm"; bool flag_rtcm_tty_port = false; + bool rtcm_file_output_enabled = false; std::string rtcm_dump_devname = "/dev/pts/4"; bool flag_rtcm_server = false; unsigned short rtcm_tcp_port = 2101; unsigned short rtcm_station_id = 1234; - std::unique_ptr RTCM_printer(new Rtcm_Printer(filename, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname)); + std::unique_ptr RTCM_printer(new Rtcm_Printer(filename, rtcm_file_output_enabled, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname)); std::string reference_msg = "D300133ED7D30202980EDEEF34B4BD62AC0941986F33360B98"; diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc index 22615cc2a..fe0c81ab6 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc @@ -330,9 +330,10 @@ TEST(RTKLibSolverTest, test1) int nchannels = 8; std::string dump_filename = ".rtklib_solver_dump.dat"; bool flag_dump_to_file = false; + bool save_to_mat = false; rtk_t rtk = configure_rtklib_options(); - std::unique_ptr d_ls_pvt(new rtklib_solver(nchannels, dump_filename, flag_dump_to_file, rtk)); + std::unique_ptr d_ls_pvt(new rtklib_solver(nchannels, dump_filename, flag_dump_to_file, save_to_mat, rtk)); d_ls_pvt->set_averaging_depth(1); // load ephemeris diff --git a/src/utils/front-end-cal/front_end_cal.cc b/src/utils/front-end-cal/front_end_cal.cc index 6b8b937ac..9fec07116 100644 --- a/src/utils/front-end-cal/front_end_cal.cc +++ b/src/utils/front-end-cal/front_end_cal.cc @@ -110,7 +110,7 @@ int FrontEndCal::Get_SUPL_Assist() supl_client_ephemeris_.server_port = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_port", 7275); supl_client_acquisition_.server_port = configuration_->property("GNSS-SDR.SUPL_gps_acquisition_port", 7275); supl_mcc = configuration_->property("GNSS-SDR.SUPL_MCC", 244); - supl_mns = configuration_->property("GNSS-SDR.SUPL_MNS", 5); + supl_mns = configuration_->property("GNSS-SDR.SUPL_MNC", 5); std::string default_lac = "0x59e2"; std::string default_ci = "0x31b0"; diff --git a/src/utils/reproducibility/ieee-access18/plot_dump.m b/src/utils/reproducibility/ieee-access18/plot_dump.m index 5865235ff..11aaba424 100644 --- a/src/utils/reproducibility/ieee-access18/plot_dump.m +++ b/src/utils/reproducibility/ieee-access18/plot_dump.m @@ -62,8 +62,8 @@ ylabel('Navigation data bits','fontname','Times','fontsize', fontsize) grid on -fileID = fopen('data/access18_pvt.dat', 'r'); -dinfo = dir('data/access18_pvt.dat'); +fileID = fopen('data/access18.dat', 'r'); +dinfo = dir('data/access18.dat'); filesize = dinfo.bytes; aux = 1; while ne(ftell(fileID), filesize) diff --git a/src/utils/rinex2assist/CMakeLists.txt b/src/utils/rinex2assist/CMakeLists.txt index 8bf5fb3a6..b7db9e90f 100644 --- a/src/utils/rinex2assist/CMakeLists.txt +++ b/src/utils/rinex2assist/CMakeLists.txt @@ -32,6 +32,8 @@ include_directories( ${GPSTK_INCLUDE_DIR} ) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated") + add_executable(rinex2assist ${CMAKE_CURRENT_SOURCE_DIR}/main.cc) target_link_libraries(rinex2assist @@ -45,7 +47,6 @@ if(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) add_dependencies(rinex2assist gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}) endif(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) - add_custom_command(TARGET rinex2assist POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_SOURCE_DIR}/install/$) diff --git a/src/utils/rinex2assist/main.cc b/src/utils/rinex2assist/main.cc index 11792d040..71b4b97fc 100644 --- a/src/utils/rinex2assist/main.cc +++ b/src/utils/rinex2assist/main.cc @@ -32,6 +32,10 @@ #include "gps_ephemeris.h" #include "galileo_ephemeris.h" +#include "gps_utc_model.h" +#include "gps_iono.h" +#include "galileo_utc_model.h" +#include "galileo_iono.h" #include #include #include @@ -49,30 +53,31 @@ int main(int argc, char** argv) "This program comes with ABSOLUTELY NO WARRANTY;\n" + "See COPYING file to see a copy of the General Public License.\n \n" + "Usage: \n" + - " rinex2assist []"); + " rinex2assist "); google::SetUsageMessage(intro_help); google::SetVersionString("1.0"); google::ParseCommandLineFlags(&argc, &argv, true); - if ((argc < 2) or (argc > 3)) + if ((argc != 2)) { std::cerr << "Usage:" << std::endl; std::cerr << " " << argv[0] - << " []" + << " " << std::endl; google::ShutDownCommandLineFlags(); return 1; } std::string xml_filename; - if (argc == 3) - { - xml_filename = argv[2]; - } std::map eph_map; std::map eph_gal_map; + Gps_Utc_Model gps_utc_model; + Gps_Iono gps_iono; + Galileo_Utc_Model gal_utc_model; + Galileo_Iono gal_iono; + int i = 0; int j = 0; try @@ -93,6 +98,53 @@ int main(int argc, char** argv) return 1; } + // Collect UTC parameters from RINEX header + if (hdr.fileSys.compare("G: (GPS)") == 0 || hdr.fileSys.compare("MIXED") == 0) + { + gps_utc_model.valid = (hdr.valid > 2147483648) ? true : false; + gps_utc_model.d_A1 = hdr.mapTimeCorr["GPUT"].A0; + gps_utc_model.d_A0 = hdr.mapTimeCorr["GPUT"].A1; + gps_utc_model.d_t_OT = hdr.mapTimeCorr["GPUT"].refSOW; + gps_utc_model.i_WN_T = hdr.mapTimeCorr["GPUT"].refWeek; + gps_utc_model.d_DeltaT_LS = hdr.leapSeconds; + gps_utc_model.i_WN_LSF = hdr.leapWeek; + gps_utc_model.i_DN = hdr.leapDay; + gps_utc_model.d_DeltaT_LSF = hdr.leapDelta; + + // Collect iono parameters from RINEX header + gps_iono.valid = (hdr.mapIonoCorr["GPSA"].param[0] == 0) ? false : true; + gps_iono.d_alpha0 = hdr.mapIonoCorr["GPSA"].param[0]; + gps_iono.d_alpha1 = hdr.mapIonoCorr["GPSA"].param[1]; + gps_iono.d_alpha2 = hdr.mapIonoCorr["GPSA"].param[2]; + gps_iono.d_alpha3 = hdr.mapIonoCorr["GPSA"].param[3]; + gps_iono.d_beta0 = hdr.mapIonoCorr["GPSB"].param[0]; + gps_iono.d_beta1 = hdr.mapIonoCorr["GPSB"].param[1]; + gps_iono.d_beta2 = hdr.mapIonoCorr["GPSB"].param[2]; + gps_iono.d_beta3 = hdr.mapIonoCorr["GPSB"].param[3]; + } + if (hdr.fileSys.compare("E: (GAL)") == 0 || hdr.fileSys.compare("MIXED") == 0) + { + gal_utc_model.A0_6 = hdr.mapTimeCorr["GAUT"].A0; + gal_utc_model.A1_6 = hdr.mapTimeCorr["GAUT"].A1; + gal_utc_model.Delta_tLS_6 = hdr.leapSeconds; + gal_utc_model.t0t_6 = hdr.mapTimeCorr["GAUT"].refSOW; + gal_utc_model.WNot_6 = hdr.mapTimeCorr["GAUT"].refWeek; + gal_utc_model.WN_LSF_6 = hdr.leapWeek; + gal_utc_model.DN_6 = hdr.leapDay; + gal_utc_model.Delta_tLSF_6 = hdr.leapDelta; + gal_utc_model.flag_utc_model = (hdr.mapTimeCorr["GAUT"].A0 == 0.0); + gal_iono.ai0_5 = hdr.mapIonoCorr["GAL"].param[0]; + gal_iono.ai1_5 = hdr.mapIonoCorr["GAL"].param[1]; + gal_iono.ai2_5 = hdr.mapIonoCorr["GAL"].param[2]; + gal_iono.Region1_flag_5 = false; + gal_iono.Region2_flag_5 = false; + gal_iono.Region3_flag_5 = false; + gal_iono.Region4_flag_5 = false; + gal_iono.Region5_flag_5 = false; + gal_iono.TOW_5 = 0.0; + gal_iono.WN_5 = 0.0; + } + // Read navigation data while (rnffs >> rne) { @@ -185,13 +237,13 @@ int main(int argc, char** argv) return 1; } - // Write XML + // Write XML ephemeris if (i != 0) { std::ofstream ofs; if (xml_filename.empty()) { - xml_filename = "eph_GPS_L1CA.xml"; + xml_filename = "gps_ephemeris.xml"; } try { @@ -201,27 +253,106 @@ int main(int argc, char** argv) } catch (std::exception& e) { - std::cerr << "Problem creating the XML file: " << e.what() << std::endl; + std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl; google::ShutDownCommandLineFlags(); return 1; } + std::cout << "Generated file: " << xml_filename << std::endl; } if (j != 0) { std::ofstream ofs2; - xml_filename = "eph_Galileo_E1.xml"; + xml_filename = "gal_ephemeris.xml"; try { ofs2.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out); boost::archive::xml_oarchive xml(ofs2); - xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", eph_gal_map); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_ephemeris_map", eph_gal_map); } catch (std::exception& e) { - std::cerr << "Problem creating the XML file: " << e.what() << std::endl; + std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl; google::ShutDownCommandLineFlags(); return 1; } + std::cout << "Generated file: " << xml_filename << std::endl; + } + + // Write XML UTC + if (gps_utc_model.valid) + { + std::ofstream ofs3; + xml_filename = "gps_utc_model.xml"; + try + { + ofs3.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs3); + xml << boost::serialization::make_nvp("GNSS-SDR_utc_model", gps_utc_model); + } + catch (std::exception& e) + { + std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + std::cout << "Generated file: " << xml_filename << std::endl; + } + + // Write XML iono + if (gps_iono.valid) + { + std::ofstream ofs4; + xml_filename = "gps_iono.xml"; + try + { + ofs4.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs4); + xml << boost::serialization::make_nvp("GNSS-SDR_iono_model", gps_iono); + } + catch (std::exception& e) + { + std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + std::cout << "Generated file: " << xml_filename << std::endl; + } + + if (gal_utc_model.A0_6 != 0) + { + std::ofstream ofs5; + xml_filename = "gal_utc_model.xml"; + try + { + ofs5.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs5); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_utc_model", gal_utc_model); + } + catch (std::exception& e) + { + std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + std::cout << "Generated file: " << xml_filename << std::endl; + } + if (gal_iono.ai0_5 != 0) + { + std::ofstream ofs7; + xml_filename = "gal_iono.xml"; + try + { + ofs7.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs7); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_iono_model", gal_iono); + } + catch (std::exception& e) + { + std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + std::cout << "Generated file: " << xml_filename << std::endl; } google::ShutDownCommandLineFlags(); return 0; diff --git a/src/utils/scripts/gnss-sdr-harness.sh b/src/utils/scripts/gnss-sdr-harness.sh new file mode 100755 index 000000000..b025bb07b --- /dev/null +++ b/src/utils/scripts/gnss-sdr-harness.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# GNSS-SDR shell script that enables the remote GNSS-SDR restart telecommand +# usage: ./gnss-sdr-harness.sh ./gnss-sdr -c config_file.conf +echo $@ +$@ +while [ $? -eq 42 ] +do + echo "restarting GNSS-SDR..." + $@ +done