diff options
Diffstat (limited to 'host/lib/usrp/gps_ctrl.cpp')
-rw-r--r-- | host/lib/usrp/gps_ctrl.cpp | 83 |
1 files changed, 44 insertions, 39 deletions
diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp index 98bc90a3f..6f5c75dec 100644 --- a/host/lib/usrp/gps_ctrl.cpp +++ b/host/lib/usrp/gps_ctrl.cpp @@ -38,7 +38,7 @@ using namespace boost::algorithm; using namespace boost::this_thread; /*! - * A GPS control for NMEA compatible GPSes + * A control for GPSDO devices */ class gps_ctrl_impl : public gps_ctrl{ @@ -63,39 +63,41 @@ private: } std::string update_cached_sensors(const std::string sensor) { - if(not gps_detected() || (gps_type != GPS_TYPE_ER_GPSDO)) { + if(not gps_detected() || (gps_type != GPS_TYPE_INTERNAL_GPSDO)) { UHD_MSG(error) << "get_stat(): unsupported GPS or no GPS detected"; return std::string(); } - std::string msg = _recv(); + const std::list<std::string> list = boost::assign::list_of("GPGGA")("GPRMC")("SERVO"); static const boost::regex status_regex("\\d\\d-\\d\\d-\\d\\d"); + std::map<std::string,std::string> msgs; + + // Get all GPSDO messages available + // Creating a map here because we only want the latest of each message type + for (std::string msg = _recv(); msg.length() > 6; msg = _recv()) + { + // Look for SERVO message + if (boost::regex_search(msg, status_regex, boost::regex_constants::match_continuous)) + msgs["SERVO"] = msg; + else + msgs[msg.substr(1,5)] = msg; + } + boost::system_time time = boost::get_system_time(); - if(msg.size() < 6) - return std::string(); - std::string nmea = msg.substr(1,5); - const std::list<std::string> list = boost::assign::list_of("GPGGA")("GPRMC"); + // Update sensors with newly read data BOOST_FOREACH(std::string key, list) { - // beginning matches one of the NMEA keys - if(!nmea.compare(key)) { - sensors[key] = boost::make_tuple(msg, time, !sensor.compare(key)); - // if this was what we're looking for return it - return (!sensor.compare(key))? msg : std::string(); - } + if (msgs[key].length()) + sensors[key] = boost::make_tuple(msgs[key], time, !sensor.compare(key)); } - //We're still here so it's not one of the NMEA strings from above - if(boost::regex_search(msg, status_regex, boost::regex_constants::match_continuous)) { - trim(msg); - sensors["SERVO"] = boost::make_tuple(msg, time, false); - if(!sensor.compare("SERVO")) - return msg; - else - return std::string(); - } + // Return requested sensor if it was updated + if (msgs[sensor].length()) + return msgs[sensor]; + return std::string(); } + public: gps_ctrl_impl(uart_iface::sptr uart){ _uart = uart; @@ -105,18 +107,19 @@ public: bool i_heard_some_nmea = false, i_heard_something_weird = false; gps_type = GPS_TYPE_NONE; + //first we look for an internal GPSDO _flush(); //get whatever junk is in the rx buffer right now, and throw it away _send("HAAAY GUYYYYS\n"); //to elicit a response from the GPSDO //wait for _send(...) to return - sleep(milliseconds(200)); + sleep(milliseconds(GPSDO_STUPID_DELAY_MS)); //then we loop until we either timeout, or until we get a response that indicates we're a JL device const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(GPS_COMM_TIMEOUT_MS); while(boost::get_system_time() < comm_timeout) { reply = _recv(); if(reply.find("Command Error") != std::string::npos) { - gps_type = GPS_TYPE_ER_GPSDO; + gps_type = GPS_TYPE_INTERNAL_GPSDO; break; } else if(reply.substr(0, 3) == "$GP") i_heard_some_nmea = true; //but keep looking for that "Command Error" response @@ -124,24 +127,25 @@ public: sleep(milliseconds(GPS_TIMEOUT_DELAY_MS)); } - if((i_heard_some_nmea) && (gps_type != GPS_TYPE_ER_GPSDO)) gps_type = GPS_TYPE_GENERIC_NMEA; + if((i_heard_some_nmea) && (gps_type != GPS_TYPE_INTERNAL_GPSDO)) gps_type = GPS_TYPE_GENERIC_NMEA; if((gps_type == GPS_TYPE_NONE) && i_heard_something_weird) { UHD_MSG(error) << "GPS invalid reply \"" << reply << "\", assuming none available" << std::endl; } switch(gps_type) { - case GPS_TYPE_ER_GPSDO: - UHD_MSG(status) << "Found an Ettus Research NMEA-capable GPSDO" << std::endl; + case GPS_TYPE_INTERNAL_GPSDO: + UHD_MSG(status) << "Found an internal GPSDO" << std::endl; init_gpsdo(); break; case GPS_TYPE_GENERIC_NMEA: - if(gps_type == GPS_TYPE_GENERIC_NMEA) UHD_MSG(status) << "Found a generic NMEA GPS device" << std::endl; + UHD_MSG(status) << "Found a generic NMEA GPS device" << std::endl; break; case GPS_TYPE_NONE: default: + UHD_MSG(status) << "No GPSDO found" << std::endl; break; } @@ -189,19 +193,19 @@ private: //issue some setup stuff so it spits out the appropriate data //none of these should issue replies so we don't bother looking for them //we have to sleep between commands because the JL device, despite not acking, takes considerable time to process each command. - sleep(milliseconds(200)); + sleep(milliseconds(GPSDO_STUPID_DELAY_MS)); _send("SYST:COMM:SER:ECHO OFF\n"); - sleep(milliseconds(200)); + sleep(milliseconds(GPSDO_STUPID_DELAY_MS)); _send("SYST:COMM:SER:PRO OFF\n"); - sleep(milliseconds(200)); + sleep(milliseconds(GPSDO_STUPID_DELAY_MS)); _send("GPS:GPGGA 1\n"); - sleep(milliseconds(200)); + sleep(milliseconds(GPSDO_STUPID_DELAY_MS)); _send("GPS:GGAST 0\n"); - sleep(milliseconds(200)); + sleep(milliseconds(GPSDO_STUPID_DELAY_MS)); _send("GPS:GPRMC 1\n"); - sleep(milliseconds(200)); + sleep(milliseconds(GPSDO_STUPID_DELAY_MS)); _send("SERV:TRAC 0\n"); - sleep(milliseconds(200)); + sleep(milliseconds(GPSDO_STUPID_DELAY_MS)); } //retrieve a raw NMEA sentence @@ -304,7 +308,7 @@ private: //enable servo reporting _send("SERV:TRAC 1\n"); - sleep(milliseconds(200)); + sleep(milliseconds(GPSDO_STUPID_DELAY_MS)); std::string reply; @@ -330,8 +334,8 @@ private: } } - std::string _recv(void){ - return _uart->read_uart(GPS_TIMEOUT_DELAY_MS/1000.); + std::string _recv(double timeout = GPS_TIMEOUT_DELAY_MS/1000.){ + return _uart->read_uart(timeout); } void _send(const std::string &buf){ @@ -339,7 +343,7 @@ private: } enum { - GPS_TYPE_ER_GPSDO, + GPS_TYPE_INTERNAL_GPSDO, GPS_TYPE_GENERIC_NMEA, GPS_TYPE_NONE } gps_type; @@ -351,6 +355,7 @@ private: static const int GPS_SERVO_FRESHNESS = 2500; static const int GPS_LOCK_FRESHNESS = 2500; static const int GPS_TIMEOUT_DELAY_MS = 200; + static const int GPSDO_STUPID_DELAY_MS = 200; }; /*********************************************************************** |