From 4dbd0467ac3dce07c1826f99355e0a9a31cf707d Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 3 May 2015 16:50:33 +0200 Subject: gps fix detector: add timeout --- doc/example.ini | 11 +++++++++-- src/DabMod.cpp | 10 ++++++++-- src/OutputUHD.cpp | 54 ++++++++++++++++++++++++++++++++++++------------------ src/OutputUHD.h | 6 ++++++ 4 files changed, 59 insertions(+), 22 deletions(-) diff --git a/doc/example.ini b/doc/example.ini index ee9d567..1c76766 100644 --- a/doc/example.ini +++ b/doc/example.ini @@ -182,17 +182,24 @@ txgain=2.0 channel=13C ; The reference clock to use. -; possible values : internal, external, MIMO +; possible values : internal, external, MIMO, gpsdo refclk_source=internal ; The reference one pulse-per second to use -; possible values : none, external, MIMO +; possible values : none, external, MIMO, gpsdo pps_source=none ; Behaviour when external clock reference lock lost ; possible values: ignore, crash behaviour_refclk_lock_lost=ignore +; The maximum accepted holdover time for the gpsdo. +; Valid only if the refclk and pps_source are set to gpsdo. +; Units: seconds +; Set to 0 to disable holdover check +; default value: 0 +max_gps_holdover_time=30 + ; section defining ZeroMQ output properties [zmqoutput] diff --git a/src/DabMod.cpp b/src/DabMod.cpp index ec1a4cd..dacc84e 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -559,6 +559,8 @@ int launch_modulator(int argc, char* argv[]) throw std::runtime_error("Configuration error"); } + outputuhd_conf.maxGPSHoldoverTime = pt.get("uhdoutput.max_gps_holdover_time", 0); + useUHDOutput = 1; } #endif @@ -671,10 +673,14 @@ int launch_modulator(int argc, char* argv[]) fprintf(stderr, " UHD\n" " Device: %s\n" " Type: %s\n" - " master_clock_rate: %ld\n", + " master_clock_rate: %ld\n" + " refclk: %s\n" + " pps source: %s\n", outputuhd_conf.device.c_str(), outputuhd_conf.usrpType.c_str(), - outputuhd_conf.masterClockRate); + outputuhd_conf.masterClockRate, + outputuhd_conf.refclk_src.c_str(), + outputuhd_conf.pps_src.c_str()); } #endif else if (useZeroMQOutput) { diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp index 090602a..06efb82 100644 --- a/src/OutputUHD.cpp +++ b/src/OutputUHD.cpp @@ -225,13 +225,15 @@ OutputUHD::OutputUHD( } else if (myConf.refclk_src == "gpsdo") { uwd.check_refclk_loss = true; - uwd.check_gpsfix = true; + uwd.check_gpsfix = (myConf.maxGPSHoldoverTime != 0); } else { uwd.check_refclk_loss = true; uwd.check_gpsfix = false; } + uwd.max_gps_holdover = myConf.maxGPSHoldoverTime; + SetDelayBuffer(config.dabMode); shared_ptr b(new barrier(2)); @@ -410,14 +412,15 @@ void UHDWorker::process_errhandler() uwd->logger->level(warn) << "UHD worker terminated"; } -bool gps_fix_ok(struct UHDWorkerData *uwd) +// Check function for GPS fixtype +bool check_gps_fix_ok(struct UHDWorkerData *uwd) { try { std::string fixtype( uwd->myUsrp->get_mboard_sensor("gps_fixtype", 0).to_pp_string()); if (fixtype.find("3d fix") == std::string::npos) { - uwd->logger->level(alert) << "OutputUHD: GPS lost fix : " << fixtype; + uwd->logger->level(warn) << "OutputUHD: " << fixtype; return false; } @@ -425,7 +428,7 @@ bool gps_fix_ok(struct UHDWorkerData *uwd) return true; } catch (uhd::lookup_error &e) { - uwd->logger->level(warn) << "no gps_fixtype sensor"; + uwd->logger->level(warn) << "OutputUHD: no gps_fixtype sensor"; return false; } } @@ -438,8 +441,10 @@ void UHDWorker::process() double last_pps = 2.0; double usrp_time; + // Variables needed for GPS fix check double last_gps_fix_check = 0.0; - const double gps_fix_check_interval = 5.0; // seconds + const double gps_fix_check_interval = 10.0; // seconds + int num_checks_without_gps_fix = 0; boost::packaged_task gps_fix_pt; boost::unique_future gps_fix_future; boost::thread gps_fix_task; @@ -547,36 +552,49 @@ void UHDWorker::process() usrp_time = uwd->myUsrp->get_time_now().get_real_secs(); if (uwd->check_gpsfix and - last_gps_fix_check + gps_fix_check_interval < usrp_time) { + // Divide interval by two because we alternate between + // launch and check + last_gps_fix_check + gps_fix_check_interval/2.0 < usrp_time) { last_gps_fix_check = usrp_time; // Alternate between launching thread and checking the // result. if (gps_fix_task.joinable()) { if (gps_fix_future.has_value()) { - uwd->logger->level(warn) << "GPSFIX " << usrp_time << - " Future ready"; gps_fix_future.wait(); gps_fix_task.join(); if (not gps_fix_future.get()) { - throw std::runtime_error("Lost GPS Fix."); + if (not num_checks_without_gps_fix) { + uwd->logger->level(alert) << + "OutputUHD: GPS Fix lost"; + } + num_checks_without_gps_fix++; + } + else { + if (num_checks_without_gps_fix) { + uwd->logger->level(info) << + "OutputUHD: GPS Fix recovered"; + } + num_checks_without_gps_fix = 0; } - } - else { - uwd->logger->level(warn) << "GPSFIX " << usrp_time << - " Future not ready yet"; - } + if (gps_fix_check_interval * num_checks_without_gps_fix > + uwd->max_gps_holdover) { + std::stringstream ss; + ss << "Lost GPS fix for " << gps_fix_check_interval * + num_checks_without_gps_fix << " seconds"; + throw std::runtime_error(ss.str()); + } + } } else { - uwd->logger->level(warn) << "GPSFIX " << usrp_time << - " Launching task"; - + // Checking the sensor here takes too much + // time, it has to be done in a separate thread. gps_fix_pt = boost::packaged_task( - boost::bind(gps_fix_ok, uwd) ); + boost::bind(check_gps_fix_ok, uwd) ); gps_fix_future = gps_fix_pt.get_future(); diff --git a/src/OutputUHD.h b/src/OutputUHD.h index 03acd94..2017f60 100644 --- a/src/OutputUHD.h +++ b/src/OutputUHD.h @@ -120,8 +120,13 @@ struct UHDWorkerData { // If we want to verify loss of refclk bool check_refclk_loss; + // If we want to check for the gps_fixtype sensor bool check_gpsfix; + // After how much time without fix we abort + int max_gps_holdover; // seconds + + // muting set by remote control bool muting; @@ -183,6 +188,7 @@ struct OutputUHDConfig { bool enableSync; bool muteNoTimestamps; unsigned dabMode; + unsigned maxGPSHoldoverTime; /* allowed values : auto, int, sma, mimo */ std::string refclk_src; -- cgit v1.2.3