mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-20 22:17:03 +00:00
Merge branch 'ttff' into next
This introduces a system test to measure the Time to First Fix. It is not built by default, must be activated by -DENABLE_SYSTEM_TESTING=ON It also adds an option to deactivate unit testing building (activated by default): -DENABLE_UNIT_TESTING=OFF
This commit is contained in:
commit
a0fc1bb86a
@ -59,6 +59,9 @@ if(ENABLE_PACKAGING)
|
|||||||
set(ENABLE_GENERIC_ARCH ON)
|
set(ENABLE_GENERIC_ARCH ON)
|
||||||
endif(ENABLE_PACKAGING)
|
endif(ENABLE_PACKAGING)
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
option(ENABLE_SYSTEM_TESTING "Builds system tests" OFF)
|
||||||
|
option(ENABLE_UNIT_TESTING "Builds unit tests" ON)
|
||||||
|
|
||||||
###############################
|
###############################
|
||||||
# GNSS-SDR version information
|
# GNSS-SDR version information
|
||||||
@ -296,29 +299,31 @@ endif(NOT ENABLE_GENERIC_ARCH)
|
|||||||
# Googletest - https://github.com/google/googletest
|
# Googletest - https://github.com/google/googletest
|
||||||
################################################################################
|
################################################################################
|
||||||
enable_testing()
|
enable_testing()
|
||||||
if(EXISTS $ENV{GTEST_DIR})
|
if(ENABLE_UNIT_TESTING OR ENABLE_SYSTEM_TESTING)
|
||||||
set(GTEST_DIR $ENV{GTEST_DIR})
|
if(EXISTS $ENV{GTEST_DIR})
|
||||||
endif(EXISTS $ENV{GTEST_DIR})
|
set(GTEST_DIR $ENV{GTEST_DIR})
|
||||||
if(GTEST_DIR)
|
endif(EXISTS $ENV{GTEST_DIR})
|
||||||
message(STATUS "Googletest root folder set at ${GTEST_DIR}")
|
if(GTEST_DIR)
|
||||||
find_path(LIBGTEST_DEV_DIR NAMES src/gtest-all.cc PATHS ${GTEST_DIR})
|
message(STATUS "Googletest root folder set at ${GTEST_DIR}")
|
||||||
if(LIBGTEST_DEV_DIR)
|
find_path(LIBGTEST_DEV_DIR NAMES src/gtest-all.cc PATHS ${GTEST_DIR})
|
||||||
message (STATUS "Googletest has been found.")
|
if(LIBGTEST_DEV_DIR)
|
||||||
else(LIBGTEST_DEV_DIR)
|
message (STATUS "Googletest has been found.")
|
||||||
message (FATAL_ERROR " Googletest source code has not been found at ${GTEST_DIR}.")
|
else(LIBGTEST_DEV_DIR)
|
||||||
endif(LIBGTEST_DEV_DIR)
|
message (FATAL_ERROR " Googletest source code has not been found at ${GTEST_DIR}.")
|
||||||
find_path(GTEST_INCLUDE_DIRS NAMES gtest/gtest.h PATHS ${GTEST_DIR}/include)
|
endif(LIBGTEST_DEV_DIR)
|
||||||
else(GTEST_DIR)
|
find_path(GTEST_INCLUDE_DIRS NAMES gtest/gtest.h PATHS ${GTEST_DIR}/include)
|
||||||
find_path(LIBGTEST_DEV_DIR NAMES src/gtest-all.cc PATHS /usr/src/gtest /opt/local/src/gtest-1.7.0)
|
else(GTEST_DIR)
|
||||||
find_path(GTEST_INCLUDE_DIRS NAMES gtest/gtest.h PATHS /usr/include /opt/local/src/gtest-1.7.0/include)
|
find_path(LIBGTEST_DEV_DIR NAMES src/gtest-all.cc PATHS /usr/src/gtest /opt/local/src/gtest-1.7.0)
|
||||||
if(LIBGTEST_DEV_DIR)
|
find_path(GTEST_INCLUDE_DIRS NAMES gtest/gtest.h PATHS /usr/include /opt/local/src/gtest-1.7.0/include)
|
||||||
message (STATUS "Googletest (libgtest-dev package) has been found.")
|
if(LIBGTEST_DEV_DIR)
|
||||||
else(LIBGTEST_DEV_DIR)
|
message (STATUS "Googletest (libgtest-dev package) has been found.")
|
||||||
message (STATUS " Googletest has not been found.")
|
else(LIBGTEST_DEV_DIR)
|
||||||
message (STATUS " Googletest will be downloaded and built automatically ")
|
message (STATUS " Googletest has not been found.")
|
||||||
message (STATUS " when doing 'make'. ")
|
message (STATUS " Googletest will be downloaded and built automatically ")
|
||||||
endif(LIBGTEST_DEV_DIR)
|
message (STATUS " when doing 'make'. ")
|
||||||
endif(GTEST_DIR)
|
endif(LIBGTEST_DEV_DIR)
|
||||||
|
endif(GTEST_DIR)
|
||||||
|
endif(ENABLE_UNIT_TESTING OR ENABLE_SYSTEM_TESTING)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,5 +19,7 @@
|
|||||||
add_subdirectory(algorithms)
|
add_subdirectory(algorithms)
|
||||||
add_subdirectory(core)
|
add_subdirectory(core)
|
||||||
add_subdirectory(main)
|
add_subdirectory(main)
|
||||||
add_subdirectory(tests)
|
if(ENABLE_UNIT_TESTING OR ENABLE_SYSTEM_TESTING)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif(ENABLE_UNIT_TESTING OR ENABLE_SYSTEM_TESTING)
|
||||||
add_subdirectory(utils)
|
add_subdirectory(utils)
|
||||||
|
@ -198,6 +198,16 @@ galileo_e1_pvt_cc::galileo_e1_pvt_cc(unsigned int nchannels, bool dump, std::str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create Sys V message queue
|
||||||
|
first_fix = true;
|
||||||
|
sysv_msg_key = 1101;
|
||||||
|
int msgflg = IPC_CREAT | 0666;
|
||||||
|
if ((sysv_msqid = msgget(sysv_msg_key, msgflg )) == -1)
|
||||||
|
{
|
||||||
|
std::cout << "GNSS-SDR can not create message queues!" << std::endl;
|
||||||
|
throw new std::exception();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -227,6 +237,21 @@ void galileo_e1_pvt_cc::print_receiver_status(Gnss_Synchro** channels_synchroniz
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool galileo_e1_pvt_cc::send_sys_v_ttff_msg(ttff_msgbuf ttff)
|
||||||
|
{
|
||||||
|
/* Fill Sys V message structures */
|
||||||
|
int msgsend_size;
|
||||||
|
ttff_msgbuf msg;
|
||||||
|
msg.ttff = ttff.ttff;
|
||||||
|
msgsend_size = sizeof(msg.ttff);
|
||||||
|
msg.mtype = 1; /* default message ID */
|
||||||
|
|
||||||
|
/* SEND SOLUTION OVER A MESSAGE QUEUE */
|
||||||
|
/* non-blocking Sys V message send */
|
||||||
|
msgsnd(sysv_msqid, &msg, msgsend_size, IPC_NOWAIT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int galileo_e1_pvt_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
|
int galileo_e1_pvt_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
|
||||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items __attribute__((unused)))
|
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items __attribute__((unused)))
|
||||||
{
|
{
|
||||||
@ -267,6 +292,17 @@ int galileo_e1_pvt_cc::general_work (int noutput_items __attribute__((unused)),
|
|||||||
|
|
||||||
if (pvt_result == true)
|
if (pvt_result == true)
|
||||||
{
|
{
|
||||||
|
if( first_fix == true)
|
||||||
|
{
|
||||||
|
std::cout << "First position fix at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time)
|
||||||
|
<< " UTC is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d
|
||||||
|
<< " [deg], Height= " << d_ls_pvt->d_height_m << " [m]" << std::endl;
|
||||||
|
ttff_msgbuf ttff;
|
||||||
|
ttff.mtype = 1;
|
||||||
|
ttff.ttff = d_sample_counter;
|
||||||
|
send_sys_v_ttff_msg(ttff);
|
||||||
|
first_fix = false;
|
||||||
|
}
|
||||||
d_kml_dump->print_position(d_ls_pvt, d_flag_averaging);
|
d_kml_dump->print_position(d_ls_pvt, d_flag_averaging);
|
||||||
d_geojson_printer->print_position(d_ls_pvt, d_flag_averaging);
|
d_geojson_printer->print_position(d_ls_pvt, d_flag_averaging);
|
||||||
d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging);
|
d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging);
|
||||||
|
@ -33,6 +33,9 @@
|
|||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/msg.h>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
#include "nmea_printer.h"
|
#include "nmea_printer.h"
|
||||||
@ -134,6 +137,15 @@ private:
|
|||||||
std::shared_ptr<galileo_e1_ls_pvt> d_ls_pvt;
|
std::shared_ptr<galileo_e1_ls_pvt> d_ls_pvt;
|
||||||
bool pseudoranges_pairCompare_min(const std::pair<int,Gnss_Synchro>& a, const std::pair<int,Gnss_Synchro>& b);
|
bool pseudoranges_pairCompare_min(const std::pair<int,Gnss_Synchro>& a, const std::pair<int,Gnss_Synchro>& b);
|
||||||
|
|
||||||
|
bool first_fix;
|
||||||
|
key_t sysv_msg_key;
|
||||||
|
int sysv_msqid;
|
||||||
|
typedef struct {
|
||||||
|
long mtype;//required by sys v message
|
||||||
|
double ttff;
|
||||||
|
} ttff_msgbuf;
|
||||||
|
bool send_sys_v_ttff_msg(ttff_msgbuf ttff);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~galileo_e1_pvt_cc (); //!< Default destructor
|
~galileo_e1_pvt_cc (); //!< Default destructor
|
||||||
|
|
||||||
|
@ -179,6 +179,21 @@ std::map<int,Gps_Ephemeris> gps_l1_ca_pvt_cc::get_GPS_L1_ephemeris_map()
|
|||||||
return d_ls_pvt->gps_ephemeris_map;
|
return d_ls_pvt->gps_ephemeris_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool gps_l1_ca_pvt_cc::send_sys_v_ttff_msg(ttff_msgbuf ttff)
|
||||||
|
{
|
||||||
|
/* Fill Sys V message structures */
|
||||||
|
int msgsend_size;
|
||||||
|
ttff_msgbuf msg;
|
||||||
|
msg.ttff = ttff.ttff;
|
||||||
|
msgsend_size = sizeof(msg.ttff);
|
||||||
|
msg.mtype = 1; /* default message ID */
|
||||||
|
|
||||||
|
/* SEND SOLUTION OVER A MESSAGE QUEUE */
|
||||||
|
/* non-blocking Sys V message send */
|
||||||
|
msgsnd(sysv_msqid, &msg, msgsend_size, IPC_NOWAIT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels,
|
gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels,
|
||||||
bool dump, std::string dump_filename,
|
bool dump, std::string dump_filename,
|
||||||
int averaging_depth,
|
int averaging_depth,
|
||||||
@ -284,6 +299,16 @@ gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create Sys V message queue
|
||||||
|
first_fix = true;
|
||||||
|
sysv_msg_key = 1101;
|
||||||
|
int msgflg = IPC_CREAT | 0666;
|
||||||
|
if ((sysv_msqid = msgget(sysv_msg_key, msgflg )) == -1)
|
||||||
|
{
|
||||||
|
std::cout << "GNSS-SDR can not create message queues!" << std::endl;
|
||||||
|
throw new std::exception();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -349,6 +374,17 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items __attribute__((unused)), g
|
|||||||
pvt_result = d_ls_pvt->get_PVT(gnss_pseudoranges_map, d_rx_time, d_flag_averaging);
|
pvt_result = d_ls_pvt->get_PVT(gnss_pseudoranges_map, d_rx_time, d_flag_averaging);
|
||||||
if (pvt_result == true)
|
if (pvt_result == true)
|
||||||
{
|
{
|
||||||
|
if( first_fix == true)
|
||||||
|
{
|
||||||
|
std::cout << "First position fix at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time)
|
||||||
|
<< " UTC is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d
|
||||||
|
<< " [deg], Height= " << d_ls_pvt->d_height_m << " [m]" << std::endl;
|
||||||
|
ttff_msgbuf ttff;
|
||||||
|
ttff.mtype = 1;
|
||||||
|
ttff.ttff = d_sample_counter;
|
||||||
|
send_sys_v_ttff_msg(ttff);
|
||||||
|
first_fix = false;
|
||||||
|
}
|
||||||
d_kml_printer->print_position(d_ls_pvt, d_flag_averaging);
|
d_kml_printer->print_position(d_ls_pvt, d_flag_averaging);
|
||||||
d_geojson_printer->print_position(d_ls_pvt, d_flag_averaging);
|
d_geojson_printer->print_position(d_ls_pvt, d_flag_averaging);
|
||||||
d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging);
|
d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging);
|
||||||
|
@ -32,6 +32,9 @@
|
|||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/msg.h>
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
#include "nmea_printer.h"
|
#include "nmea_printer.h"
|
||||||
#include "kml_printer.h"
|
#include "kml_printer.h"
|
||||||
@ -137,6 +140,15 @@ private:
|
|||||||
|
|
||||||
std::map<int,Gnss_Synchro> gnss_pseudoranges_map;
|
std::map<int,Gnss_Synchro> gnss_pseudoranges_map;
|
||||||
|
|
||||||
|
bool first_fix;
|
||||||
|
key_t sysv_msg_key;
|
||||||
|
int sysv_msqid;
|
||||||
|
typedef struct {
|
||||||
|
long mtype;//required by sys v message
|
||||||
|
double ttff;
|
||||||
|
} ttff_msgbuf;
|
||||||
|
bool send_sys_v_ttff_msg(ttff_msgbuf ttff);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -275,6 +275,16 @@ hybrid_pvt_cc::hybrid_pvt_cc(unsigned int nchannels, bool dump, std::string dump
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create Sys V message queue
|
||||||
|
first_fix = true;
|
||||||
|
sysv_msg_key = 1101;
|
||||||
|
int msgflg = IPC_CREAT | 0666;
|
||||||
|
if ((sysv_msqid = msgget(sysv_msg_key, msgflg )) == -1)
|
||||||
|
{
|
||||||
|
std::cout << "GNSS-SDR can not create message queues!" << std::endl;
|
||||||
|
throw new std::exception();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -304,6 +314,22 @@ void hybrid_pvt_cc::print_receiver_status(Gnss_Synchro** channels_synchronizatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool hybrid_pvt_cc::send_sys_v_ttff_msg(ttff_msgbuf ttff)
|
||||||
|
{
|
||||||
|
/* Fill Sys V message structures */
|
||||||
|
int msgsend_size;
|
||||||
|
ttff_msgbuf msg;
|
||||||
|
msg.ttff = ttff.ttff;
|
||||||
|
msgsend_size = sizeof(msg.ttff);
|
||||||
|
msg.mtype = 1; /* default message ID */
|
||||||
|
|
||||||
|
/* SEND SOLUTION OVER A MESSAGE QUEUE */
|
||||||
|
/* non-blocking Sys V message send */
|
||||||
|
msgsnd(sysv_msqid, &msg, msgsend_size, IPC_NOWAIT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int hybrid_pvt_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
|
int hybrid_pvt_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
|
||||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items __attribute__((unused)))
|
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items __attribute__((unused)))
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,9 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/msg.h>
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
#include "nmea_printer.h"
|
#include "nmea_printer.h"
|
||||||
#include "kml_printer.h"
|
#include "kml_printer.h"
|
||||||
@ -137,6 +140,15 @@ private:
|
|||||||
std::map<int,Gnss_Synchro> gnss_pseudoranges_map;
|
std::map<int,Gnss_Synchro> gnss_pseudoranges_map;
|
||||||
bool pseudoranges_pairCompare_min(const std::pair<int,Gnss_Synchro>& a, const std::pair<int,Gnss_Synchro>& b);
|
bool pseudoranges_pairCompare_min(const std::pair<int,Gnss_Synchro>& a, const std::pair<int,Gnss_Synchro>& b);
|
||||||
|
|
||||||
|
bool first_fix;
|
||||||
|
key_t sysv_msg_key;
|
||||||
|
int sysv_msqid;
|
||||||
|
typedef struct {
|
||||||
|
long mtype;//required by sys v message
|
||||||
|
double ttff;
|
||||||
|
} ttff_msgbuf;
|
||||||
|
bool send_sys_v_ttff_msg(ttff_msgbuf ttff);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
* \brief Get latest set of GPS L1 ephemeris from PVT block
|
* \brief Get latest set of GPS L1 ephemeris from PVT block
|
||||||
|
@ -37,6 +37,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/msg.h>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/chrono.hpp>
|
#include <boost/chrono.hpp>
|
||||||
#include <gnuradio/message.h>
|
#include <gnuradio/message.h>
|
||||||
@ -126,6 +129,7 @@ void ControlThread::run()
|
|||||||
assist_GNSS();
|
assist_GNSS();
|
||||||
// start the keyboard_listener thread
|
// start the keyboard_listener thread
|
||||||
keyboard_thread_ = boost::thread(&ControlThread::keyboard_listener, this);
|
keyboard_thread_ = boost::thread(&ControlThread::keyboard_listener, this);
|
||||||
|
sysv_queue_thread_ = boost::thread(&ControlThread::sysv_queue_listener, this);
|
||||||
|
|
||||||
// Main loop to read and process the control messages
|
// Main loop to read and process the control messages
|
||||||
while (flowgraph_->running() && !stop_)
|
while (flowgraph_->running() && !stop_)
|
||||||
@ -141,9 +145,11 @@ void ControlThread::run()
|
|||||||
//Join keyboard thread
|
//Join keyboard thread
|
||||||
#ifdef OLD_BOOST
|
#ifdef OLD_BOOST
|
||||||
keyboard_thread_.timed_join(boost::posix_time::seconds(1));
|
keyboard_thread_.timed_join(boost::posix_time::seconds(1));
|
||||||
|
sysv_queue_thread_.timed_join(boost::posix_time::seconds(1));
|
||||||
#endif
|
#endif
|
||||||
#ifndef OLD_BOOST
|
#ifndef OLD_BOOST
|
||||||
keyboard_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000));
|
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));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LOG(INFO) << "Flowgraph stopped";
|
LOG(INFO) << "Flowgraph stopped";
|
||||||
@ -510,6 +516,41 @@ void ControlThread::gps_acq_assist_data_collector()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ControlThread::sysv_queue_listener()
|
||||||
|
{
|
||||||
|
typedef struct {
|
||||||
|
long mtype; //required by sys v message
|
||||||
|
double ttff;
|
||||||
|
} ttff_msgbuf;
|
||||||
|
bool read_queue = true;
|
||||||
|
ttff_msgbuf msg;
|
||||||
|
double ttff_msg = 0.0;
|
||||||
|
int msgrcv_size = sizeof(msg.ttff);
|
||||||
|
int msqid;
|
||||||
|
key_t key = 1102;
|
||||||
|
// wait for the queue to be created
|
||||||
|
|
||||||
|
while(read_queue)
|
||||||
|
{
|
||||||
|
while((msqid = msgget(key, 0644)) == -1){}
|
||||||
|
if (msgrcv(msqid, &msg, msgrcv_size, 1, 0) != -1)
|
||||||
|
{
|
||||||
|
|
||||||
|
ttff_msg = msg.ttff;
|
||||||
|
if(ttff_msg == 200)
|
||||||
|
{
|
||||||
|
std::cout << "Quit order received, stopping GNSS-SDR !!" << std::endl;
|
||||||
|
std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
|
||||||
|
if (control_queue_ != gr::msg_queue::sptr())
|
||||||
|
{
|
||||||
|
control_queue_->handle(cmf->GetQueueMessage(200, 0));
|
||||||
|
}
|
||||||
|
read_queue = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::keyboard_listener()
|
void ControlThread::keyboard_listener()
|
||||||
{
|
{
|
||||||
|
@ -155,9 +155,11 @@ private:
|
|||||||
unsigned int processed_control_messages_;
|
unsigned int processed_control_messages_;
|
||||||
unsigned int applied_actions_;
|
unsigned int applied_actions_;
|
||||||
boost::thread keyboard_thread_;
|
boost::thread keyboard_thread_;
|
||||||
|
boost::thread sysv_queue_thread_;
|
||||||
boost::thread gps_acq_assist_data_collector_thread_;
|
boost::thread gps_acq_assist_data_collector_thread_;
|
||||||
|
|
||||||
void keyboard_listener();
|
void keyboard_listener();
|
||||||
|
void sysv_queue_listener();
|
||||||
|
|
||||||
// default filename for assistance data
|
// default filename for assistance data
|
||||||
const std::string eph_default_xml_filename = "./gps_ephemeris.xml";
|
const std::string eph_default_xml_filename = "./gps_ephemeris.xml";
|
||||||
|
@ -36,7 +36,9 @@
|
|||||||
#include "string_converter.h"
|
#include "string_converter.h"
|
||||||
|
|
||||||
InMemoryConfiguration::InMemoryConfiguration()
|
InMemoryConfiguration::InMemoryConfiguration()
|
||||||
{}
|
{
|
||||||
|
std::unique_ptr<StringConverter> converter_(new StringConverter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
InMemoryConfiguration::~InMemoryConfiguration()
|
InMemoryConfiguration::~InMemoryConfiguration()
|
||||||
|
@ -164,14 +164,14 @@ endif(ENABLE_CUDA)
|
|||||||
|
|
||||||
add_definitions(-DTEST_PATH="${CMAKE_SOURCE_DIR}/src/tests/")
|
add_definitions(-DTEST_PATH="${CMAKE_SOURCE_DIR}/src/tests/")
|
||||||
|
|
||||||
|
if(ENABLE_UNIT_TESTING)
|
||||||
|
add_executable(run_tests ${CMAKE_CURRENT_SOURCE_DIR}/test_main.cc)
|
||||||
|
|
||||||
add_executable(run_tests ${CMAKE_CURRENT_SOURCE_DIR}/test_main.cc)
|
add_custom_command(TARGET run_tests POST_BUILD
|
||||||
|
|
||||||
add_custom_command(TARGET run_tests POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:run_tests>
|
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:run_tests>
|
||||||
${CMAKE_SOURCE_DIR}/install/$<TARGET_FILE_NAME:run_tests>)
|
${CMAKE_SOURCE_DIR}/install/$<TARGET_FILE_NAME:run_tests>)
|
||||||
|
|
||||||
target_link_libraries(run_tests ${CLANG_FLAGS}
|
target_link_libraries(run_tests ${CLANG_FLAGS}
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
${GFLAGS_LIBS}
|
${GFLAGS_LIBS}
|
||||||
${GLOG_LIBRARIES}
|
${GLOG_LIBRARIES}
|
||||||
@ -191,8 +191,8 @@ target_link_libraries(run_tests ${CLANG_FLAGS}
|
|||||||
pvt_gr_blocks
|
pvt_gr_blocks
|
||||||
${VOLK_GNSSSDR_LIBRARIES} ${ORC_LIBRARIES}
|
${VOLK_GNSSSDR_LIBRARIES} ${ORC_LIBRARIES}
|
||||||
${GNSS_SDR_TEST_OPTIONAL_LIBS}
|
${GNSS_SDR_TEST_OPTIONAL_LIBS}
|
||||||
)
|
)
|
||||||
|
endif(ENABLE_UNIT_TESTING)
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# Adding Tests to Ctest
|
# Adding Tests to Ctest
|
||||||
@ -372,3 +372,33 @@ endif(NOT ${GTEST_DIR_LOCAL})
|
|||||||
|
|
||||||
add_dependencies(check control_thread_test flowgraph_test gnss_block_test
|
add_dependencies(check control_thread_test flowgraph_test gnss_block_test
|
||||||
gnuradio_block_test trk_test)
|
gnuradio_block_test trk_test)
|
||||||
|
|
||||||
|
|
||||||
|
# Addition of System Tests
|
||||||
|
if(ENABLE_SYSTEM_TESTING)
|
||||||
|
add_executable(ttff
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/system-tests/ttff_gps_l1.cc )
|
||||||
|
if(NOT ${GTEST_DIR_LOCAL})
|
||||||
|
add_dependencies(ttff gtest-${gtest_RELEASE})
|
||||||
|
else(NOT ${GTEST_DIR_LOCAL})
|
||||||
|
add_dependencies(ttff gtest)
|
||||||
|
endif(NOT ${GTEST_DIR_LOCAL})
|
||||||
|
target_link_libraries(ttff
|
||||||
|
${Boost_LIBRARIES}
|
||||||
|
${GFLAGS_LIBS}
|
||||||
|
${GLOG_LIBRARIES}
|
||||||
|
${GTEST_LIBRARIES}
|
||||||
|
${GNURADIO_RUNTIME_LIBRARIES}
|
||||||
|
${GNURADIO_BLOCKS_LIBRARIES}
|
||||||
|
${GNURADIO_FILTER_LIBRARIES}
|
||||||
|
${GNURADIO_ANALOG_LIBRARIES}
|
||||||
|
${VOLK_GNSSSDR_LIBRARIES} ${ORC_LIBRARIES}
|
||||||
|
gnss_sp_libs
|
||||||
|
gnss_rx
|
||||||
|
gnss_system_parameters
|
||||||
|
)
|
||||||
|
add_custom_command(TARGET ttff POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:ttff>
|
||||||
|
${CMAKE_SOURCE_DIR}/install/$<TARGET_FILE_NAME:ttff>
|
||||||
|
)
|
||||||
|
endif(ENABLE_SYSTEM_TESTING)
|
409
src/tests/system-tests/ttff_gps_l1.cc
Normal file
409
src/tests/system-tests/ttff_gps_l1.cc
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
/*!
|
||||||
|
* \file ttff_gps_l1.cc
|
||||||
|
* \brief This class implements a test for measuring
|
||||||
|
* the Time-To-First-Fix
|
||||||
|
* \author Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2016 (see AUTHORS file for a list of contributors)
|
||||||
|
*
|
||||||
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
|
* Satellite Systems receiver
|
||||||
|
*
|
||||||
|
* This file is part of GNSS-SDR.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
#include <numeric>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/msg.h>
|
||||||
|
#include <thread>
|
||||||
|
#include <gflags/gflags.h>
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include "concurrent_map.h"
|
||||||
|
#include "concurrent_queue.h"
|
||||||
|
#include "control_thread.h"
|
||||||
|
#include "file_configuration.h"
|
||||||
|
#include "in_memory_configuration.h"
|
||||||
|
#include "gnss_flowgraph.h"
|
||||||
|
#include "gps_acq_assist.h"
|
||||||
|
|
||||||
|
|
||||||
|
DEFINE_int32(fs_in, 4000000, "Sampling rate, in Ms/s");
|
||||||
|
DEFINE_int32(max_measurement_duration, 90, "Maximum time waiting for a position fix, in seconds");
|
||||||
|
DEFINE_int32(num_measurements, 2, "Number of measurements");
|
||||||
|
DEFINE_string(device_address, "192.168.40.2", "USRP device IP address");
|
||||||
|
DEFINE_string(subdevice, "A:0", "USRP subdevice");
|
||||||
|
|
||||||
|
|
||||||
|
// For GPS NAVIGATION (L1)
|
||||||
|
concurrent_queue<Gps_Acq_Assist> global_gps_acq_assist_queue;
|
||||||
|
concurrent_map<Gps_Acq_Assist> global_gps_acq_assist_map;
|
||||||
|
|
||||||
|
std::vector<double> TTFF_v;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
long mtype; // required by SysV message
|
||||||
|
double ttff;
|
||||||
|
} ttff_msgbuf;
|
||||||
|
|
||||||
|
const int decimation_factor = 1;
|
||||||
|
|
||||||
|
class TTFF_GPS_L1_CA_Test: public ::testing::Test
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void config_1();
|
||||||
|
void config_2();
|
||||||
|
void print_TTFF_report(const std::vector<double> & ttff_v);
|
||||||
|
|
||||||
|
std::shared_ptr<InMemoryConfiguration> config;
|
||||||
|
std::shared_ptr<FileConfiguration> config2;
|
||||||
|
|
||||||
|
const double central_freq = 1575420000.0;
|
||||||
|
const double gain_dB = 40.0;
|
||||||
|
|
||||||
|
const int number_of_taps = 11;
|
||||||
|
const int number_of_bands = 2;
|
||||||
|
const float band1_begin = 0.0;
|
||||||
|
const float band1_end = 0.48;
|
||||||
|
const float band2_begin = 0.52;
|
||||||
|
const float band2_end = 1.0;
|
||||||
|
const float ampl1_begin = 1.0;
|
||||||
|
const float ampl1_end = 1.0;
|
||||||
|
const float ampl2_begin = 0.0;
|
||||||
|
const float ampl2_end = 0.0;
|
||||||
|
const float band1_error = 1.0;
|
||||||
|
const float band2_error = 1.0;
|
||||||
|
const int grid_density = 16;
|
||||||
|
const float zero = 0.0;
|
||||||
|
const int number_of_channels = 8;
|
||||||
|
const int in_acquisition = 1;
|
||||||
|
|
||||||
|
const float threshold = 0.01;
|
||||||
|
const float doppler_max = 8000.0;
|
||||||
|
const float doppler_step = 500.0;
|
||||||
|
const int max_dwells = 1;
|
||||||
|
const int tong_init_val = 2;
|
||||||
|
const int tong_max_val = 10;
|
||||||
|
const int tong_max_dwells = 30;
|
||||||
|
const int coherent_integration_time_ms = 1;
|
||||||
|
|
||||||
|
const float pll_bw_hz = 30.0;
|
||||||
|
const float dll_bw_hz = 4.0;
|
||||||
|
const float early_late_space_chips = 0.5;
|
||||||
|
|
||||||
|
const int display_rate_ms = 500;
|
||||||
|
const int output_rate_ms = 100;
|
||||||
|
const int averaging_depth = 10;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void TTFF_GPS_L1_CA_Test::config_1()
|
||||||
|
{
|
||||||
|
config = std::make_shared<InMemoryConfiguration>();
|
||||||
|
// Set the Signal Source
|
||||||
|
config->set_property("GNSS-SDR.internal_fs_hz", std::to_string(FLAGS_fs_in));
|
||||||
|
config->set_property("SignalSource.item_type", "cshort");
|
||||||
|
config->set_property("SignalSource.implementation", "UHD_Signal_Source");
|
||||||
|
config->set_property("SignalSource.freq", std::to_string(central_freq));
|
||||||
|
config->set_property("SignalSource.sampling_frequency", std::to_string(FLAGS_fs_in));
|
||||||
|
config->set_property("SignalSource.gain", std::to_string(gain_dB));
|
||||||
|
config->set_property("SignalSource.subdevice", FLAGS_subdevice);
|
||||||
|
config->set_property("SignalSource.samples", std::to_string(FLAGS_fs_in * FLAGS_max_measurement_duration));
|
||||||
|
config->set_property("SignalSource.device_address", FLAGS_device_address);
|
||||||
|
|
||||||
|
// Set the Signal Conditioner
|
||||||
|
config->set_property("SignalConditioner.implementation", "Signal_Conditioner");
|
||||||
|
config->set_property("DataTypeAdapter.implementation", "Pass_Through");
|
||||||
|
config->set_property("DataTypeAdapter.item_type", "cshort");
|
||||||
|
config->set_property("InputFilter.implementation", "Fir_Filter");
|
||||||
|
config->set_property("InputFilter.dump", "false");
|
||||||
|
config->set_property("InputFilter.input_item_type", "cshort");
|
||||||
|
config->set_property("InputFilter.output_item_type", "gr_complex");
|
||||||
|
config->set_property("InputFilter.taps_item_type", "float");
|
||||||
|
config->set_property("InputFilter.number_of_taps", std::to_string(number_of_taps));
|
||||||
|
config->set_property("InputFilter.number_of_bands", std::to_string(number_of_bands));
|
||||||
|
config->set_property("InputFilter.band1_begin", std::to_string(band1_begin));
|
||||||
|
config->set_property("InputFilter.band1_end", std::to_string(band1_end));
|
||||||
|
config->set_property("InputFilter.band2_begin", std::to_string(band2_begin));
|
||||||
|
config->set_property("InputFilter.band2_end", std::to_string(band2_end));
|
||||||
|
config->set_property("InputFilter.ampl1_begin", std::to_string(ampl1_begin));
|
||||||
|
config->set_property("InputFilter.ampl1_end", std::to_string(ampl1_end));
|
||||||
|
config->set_property("InputFilter.ampl2_begin", std::to_string(ampl2_begin));
|
||||||
|
config->set_property("InputFilter.ampl2_end", std::to_string(ampl2_end));
|
||||||
|
config->set_property("InputFilter.band1_error", std::to_string(band1_error));
|
||||||
|
config->set_property("InputFilter.band2_error", std::to_string(band2_error));
|
||||||
|
config->set_property("InputFilter.filter_type", "bandpass");
|
||||||
|
config->set_property("InputFilter.grid_density", std::to_string(grid_density));
|
||||||
|
config->set_property("InputFilter.sampling_frequency", std::to_string(FLAGS_fs_in));
|
||||||
|
config->set_property("InputFilter.IF", std::to_string(zero));
|
||||||
|
config->set_property("Resampler.implementation", "Pass_Through");
|
||||||
|
config->set_property("Resampler.dump", "false");
|
||||||
|
config->set_property("Resampler.item_type", "gr_complex");
|
||||||
|
config->set_property("Resampler.sample_freq_in", std::to_string(FLAGS_fs_in));
|
||||||
|
config->set_property("Resampler.sample_freq_out", std::to_string(FLAGS_fs_in));
|
||||||
|
|
||||||
|
// Set the number of Channels
|
||||||
|
config->set_property("Channels_1C.count", std::to_string(number_of_channels));
|
||||||
|
config->set_property("Channels.in_acquisition", std::to_string(in_acquisition));
|
||||||
|
config->set_property("Channel.signal", "1C");
|
||||||
|
|
||||||
|
// Set Acquisition
|
||||||
|
config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Tong_Acquisition");
|
||||||
|
config->set_property("Acquisition_1C.item_type", "gr_complex");
|
||||||
|
config->set_property("Acquisition_1C.if", std::to_string(zero));
|
||||||
|
config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms));
|
||||||
|
config->set_property("Acquisition_1C.threshold", std::to_string(threshold));
|
||||||
|
config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max));
|
||||||
|
config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step));
|
||||||
|
config->set_property("Acquisition_1C.bit_transition_flag", "false");
|
||||||
|
config->set_property("Acquisition_1C.max_dwells", std::to_string(max_dwells));
|
||||||
|
config->set_property("Acquisition_1C.tong_init_val", std::to_string(tong_init_val));
|
||||||
|
config->set_property("Acquisition_1C.tong_max_val", std::to_string(tong_max_val));
|
||||||
|
config->set_property("Acquisition_1C.tong_max_dwells", std::to_string(tong_max_dwells));
|
||||||
|
|
||||||
|
// Set Tracking
|
||||||
|
config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_Tracking");
|
||||||
|
config->set_property("Tracking_1C.item_type", "gr_complex");
|
||||||
|
config->set_property("Tracking_1C.if", std::to_string(zero));
|
||||||
|
config->set_property("Tracking_1C.dump", "false");
|
||||||
|
config->set_property("Tracking_1C.dump_filename", "./tracking_ch_");
|
||||||
|
config->set_property("Tracking_1C.pll_bw_hz", std::to_string(pll_bw_hz));
|
||||||
|
config->set_property("Tracking_1C.dll_bw_hz", std::to_string(dll_bw_hz));
|
||||||
|
config->set_property("Tracking_1C.early_late_space_chips", std::to_string(early_late_space_chips));
|
||||||
|
|
||||||
|
// Set Telemetry
|
||||||
|
config->set_property("TelemetryDecoder_1C.implementation", "GPS_L1_CA_Telemetry_Decoder");
|
||||||
|
config->set_property("TelemetryDecoder_1C.dump", "false");
|
||||||
|
config->set_property("TelemetryDecoder_1C.decimation_factor", std::to_string(decimation_factor));
|
||||||
|
|
||||||
|
// Set Observables
|
||||||
|
config->set_property("Observables.implementation", "GPS_L1_CA_Observables");
|
||||||
|
config->set_property("Observables.dump", "false");
|
||||||
|
config->set_property("Observables.dump_filename", "./observables.dat");
|
||||||
|
|
||||||
|
// Set PVT
|
||||||
|
config->set_property("PVT.implementation", "GPS_L1_CA_PVT");
|
||||||
|
config->set_property("PVT.averaging_depth", std::to_string(averaging_depth));
|
||||||
|
config->set_property("PVT.flag_averaging", "true");
|
||||||
|
config->set_property("PVT.output_rate_ms", std::to_string(output_rate_ms));
|
||||||
|
config->set_property("PVT.display_rate_ms", std::to_string(display_rate_ms));
|
||||||
|
config->set_property("PVT.dump_filename", "./PVT");
|
||||||
|
config->set_property("PVT.nmea_dump_filename", "./gnss_sdr_pvt.nmea");
|
||||||
|
config->set_property("PVT.flag_nmea_tty_port", "false");
|
||||||
|
config->set_property("PVT.nmea_dump_devname", "/dev/pts/4");
|
||||||
|
config->set_property("PVT.flag_rtcm_server", "false");
|
||||||
|
config->set_property("PVT.flag_rtcm_tty_port", "false");
|
||||||
|
config->set_property("PVT.rtcm_dump_devname", "/dev/pts/1");
|
||||||
|
config->set_property("PVT.dump", "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TTFF_GPS_L1_CA_Test::config_2()
|
||||||
|
{
|
||||||
|
std::string path = std::string(TEST_PATH);
|
||||||
|
std::string filename = path + "../../conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf";
|
||||||
|
config2 = std::make_shared<FileConfiguration>(filename);
|
||||||
|
config2->set_property("SignalSource.samples", std::to_string(FLAGS_fs_in * FLAGS_max_measurement_duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void receive_msg()
|
||||||
|
{
|
||||||
|
ttff_msgbuf msg;
|
||||||
|
ttff_msgbuf msg_stop;
|
||||||
|
msg_stop.mtype = 1;
|
||||||
|
msg_stop.ttff = 200;
|
||||||
|
double ttff_msg = 0.0;
|
||||||
|
int msgrcv_size = sizeof(msg.ttff);
|
||||||
|
int msqid;
|
||||||
|
int msqid_stop;
|
||||||
|
key_t key = 1101;
|
||||||
|
key_t key_stop = 1102;
|
||||||
|
// wait for the queue to be created
|
||||||
|
while((msqid = msgget(key, 0644)) == -1){}
|
||||||
|
|
||||||
|
if (msgrcv(msqid, &msg, msgrcv_size, 1, 0) != -1)
|
||||||
|
{
|
||||||
|
ttff_msg = msg.ttff;
|
||||||
|
if( (ttff_msg != 0) && (ttff_msg != -1))
|
||||||
|
{
|
||||||
|
TTFF_v.push_back(ttff_msg / (1000.0 / decimation_factor) );
|
||||||
|
LOG(INFO) << "Valid Time-To-First-Fix: " << ttff_msg / (1000.0 / decimation_factor ) << "[s]";
|
||||||
|
// Stop the receiver
|
||||||
|
while((msqid_stop = msgget(key_stop, 0644)) == -1){}
|
||||||
|
double msgsend_size = sizeof(msg_stop.ttff);
|
||||||
|
msgsnd(msqid_stop, &msg_stop, msgsend_size, IPC_NOWAIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ttff_msg != -1)
|
||||||
|
{
|
||||||
|
receive_msg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TTFF_GPS_L1_CA_Test::print_TTFF_report(const std::vector<double> & ttff_v)
|
||||||
|
{
|
||||||
|
std::vector<double> ttff = ttff_v;
|
||||||
|
double sum = std::accumulate(ttff.begin(), ttff.end(), 0.0);
|
||||||
|
double mean = sum / ttff.size();
|
||||||
|
double sq_sum = std::inner_product(ttff.begin(), ttff.end(), ttff.begin(), 0.0);
|
||||||
|
double stdev = std::sqrt(sq_sum / ttff.size() - mean * mean);
|
||||||
|
auto max_ttff = std::max_element(std::begin(ttff), std::end(ttff));
|
||||||
|
auto min_ttff = std::min_element(std::begin(ttff), std::end(ttff));
|
||||||
|
std::cout << "---------------------------" << std::endl;
|
||||||
|
std::cout << " Time-To-First-Fix Report" << std::endl;
|
||||||
|
std::cout << "---------------------------" << std::endl;
|
||||||
|
std::cout << "Valid measurements (" << ttff.size() << "/" << FLAGS_num_measurements << "): ";
|
||||||
|
for(double ttff_ : ttff) std::cout << ttff_ << " ";
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "TTFF mean: " << mean << " [s]" << std::endl;
|
||||||
|
if (ttff.size() > 0)
|
||||||
|
{
|
||||||
|
std::cout << "TTFF max: " << *max_ttff << " [s]" << std::endl;
|
||||||
|
std::cout << "TTFF min: " << *min_ttff << " [s]" << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "TTFF stdev: " << stdev << " [s]" << std::endl;
|
||||||
|
std::cout << "---------------------------" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_F(TTFF_GPS_L1_CA_Test, ColdStart)
|
||||||
|
{
|
||||||
|
unsigned int num_measurements = 0;
|
||||||
|
|
||||||
|
config_1();
|
||||||
|
// Ensure Cold Start
|
||||||
|
config->set_property("GNSS-SDR.SUPL_gps_enabled", "false");
|
||||||
|
config->set_property("GNSS-SDR.SUPL_read_gps_assistance_xml", "false");
|
||||||
|
|
||||||
|
config_2();
|
||||||
|
// Ensure Cold Start
|
||||||
|
config2->set_property("GNSS-SDR.SUPL_read_gps_assistance_xml", "false");
|
||||||
|
config2->set_property("GNSS-SDR.SUPL_read_gps_assistance_xml", "false");
|
||||||
|
config2->set_property("PVT.flag_rtcm_server", "false");
|
||||||
|
|
||||||
|
for(int n = 0; n < FLAGS_num_measurements; n++)
|
||||||
|
{
|
||||||
|
// Create a new ControlThread object with a smart pointer
|
||||||
|
std::unique_ptr<ControlThread> control_thread(new ControlThread(config));
|
||||||
|
|
||||||
|
// record startup time
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
long long int begin = tv.tv_sec * 1000000 + tv.tv_usec;
|
||||||
|
|
||||||
|
std::cout << "Starting measurement " << num_measurements + 1 << " / " << FLAGS_num_measurements << std::endl;
|
||||||
|
|
||||||
|
// start receiver
|
||||||
|
try
|
||||||
|
{
|
||||||
|
control_thread->run();
|
||||||
|
}
|
||||||
|
catch( boost::exception & e )
|
||||||
|
{
|
||||||
|
std::cout << "Boost exception: " << boost::diagnostic_information(e);
|
||||||
|
}
|
||||||
|
catch(std::exception const& ex)
|
||||||
|
{
|
||||||
|
std::cout << "STD exception: " << ex.what();
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop clock
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
long long int end = tv.tv_sec * 1000000 + tv.tv_usec;
|
||||||
|
double ttff = static_cast<double>(end - begin) / 1000000.0;
|
||||||
|
|
||||||
|
std::shared_ptr<GNSSFlowgraph> flowgraph = control_thread->flowgraph();
|
||||||
|
EXPECT_FALSE(flowgraph->running());
|
||||||
|
|
||||||
|
num_measurements = num_measurements + 1;
|
||||||
|
std::cout << "Just finished measurement " << num_measurements << ", which took " << ttff << " seconds." << std::endl;
|
||||||
|
if(n < FLAGS_num_measurements - 1)
|
||||||
|
{
|
||||||
|
std::srand(std::time(0)); // use current time as seed for random generator
|
||||||
|
int random_variable = std::rand();
|
||||||
|
float random_variable_0_1 = static_cast<float>(random_variable) / static_cast<float>( RAND_MAX );
|
||||||
|
int random_delay_s = static_cast<int>(random_variable_0_1 * 25.0);
|
||||||
|
std::cout << "Waiting a random amount of time (from 5 to 30 s) to start new measurement... " << std::endl;
|
||||||
|
std::cout << "This time will wait " << random_delay_s + 5 << " s." << std::endl << std::endl;
|
||||||
|
std::this_thread::sleep_until(std::chrono::system_clock::now() + std::chrono::seconds(5) + std::chrono::seconds(random_delay_s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print TTFF report
|
||||||
|
print_TTFF_report(TTFF_v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
std::cout << "Running Time-To-First-Fix test..." << std::endl;
|
||||||
|
int res = 0;
|
||||||
|
TTFF_v.clear();
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
google::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
|
google::InitGoogleLogging(argv[0]);
|
||||||
|
|
||||||
|
// Create SysV message queue to read TFFF measurements
|
||||||
|
key_t sysv_msg_key;
|
||||||
|
int sysv_msqid;
|
||||||
|
sysv_msg_key = 1101;
|
||||||
|
int msgflg = IPC_CREAT | 0666;
|
||||||
|
if ((sysv_msqid = msgget(sysv_msg_key, msgflg )) == -1)
|
||||||
|
{
|
||||||
|
std::cout<<"GNSS-SDR can not create message queues!" << std::endl;
|
||||||
|
throw new std::exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Start queue thread
|
||||||
|
std::thread receive_msg_thread(receive_msg);
|
||||||
|
|
||||||
|
// Run the Tests
|
||||||
|
try
|
||||||
|
{
|
||||||
|
res = RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
LOG(WARNING) << "Unexpected catch";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terminate the queue thread
|
||||||
|
ttff_msgbuf msg;
|
||||||
|
msg.mtype = 1;
|
||||||
|
msg.ttff = -1;
|
||||||
|
int msgsend_size;
|
||||||
|
msgsend_size = sizeof(msg.ttff);
|
||||||
|
msgsnd(sysv_msqid, &msg, msgsend_size, IPC_NOWAIT);
|
||||||
|
receive_msg_thread.join();
|
||||||
|
google::ShutDownCommandLineFlags();
|
||||||
|
return res;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user