1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-13 19:50:34 +00:00

Now the software recognizes the satellite block to which the SV belongs.

Experimental storage of ephemeris in RINEX NAV file.

Some double variables are now int.

The nav message header and data Rinex printer handles both versions 2.11 and 3.01.

Change of filename: rinex_2_1_printer is now rinex_printer.

Class rinex_printer is now Rinex_Printer.

git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@117 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
Carles Fernandez 2012-01-10 08:43:58 +00:00
parent a555102566
commit ca960b96e9
15 changed files with 941 additions and 484 deletions

View File

@ -4,7 +4,7 @@
* \author Javier Arribas, 2011. jarribas(at)cttc.es * \author Javier Arribas, 2011. jarribas(at)cttc.es
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -27,6 +27,7 @@
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*/ */
#include "gps_l1_ca_pvt_cc.h"
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
@ -38,9 +39,8 @@
#include <gnuradio/gr_io_signature.h> #include <gnuradio/gr_io_signature.h>
#include <glog/log_severity.h> #include <glog/log_severity.h>
#include <glog/logging.h> #include <glog/logging.h>
#include "gps_l1_ca_pvt_cc.h"
#include "control_message_factory.h" #include "control_message_factory.h"
#include "rinex_2_1_printer.h"
using google::LogMessage; using google::LogMessage;
@ -77,7 +77,7 @@ gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr que
d_sample_counter=0; d_sample_counter=0;
b_rinex_header_writen = false; b_rinex_header_writen = false;
rp = new rinex_printer(); rp = new Rinex_Printer();
} }
gps_l1_ca_pvt_cc::~gps_l1_ca_pvt_cc() { gps_l1_ca_pvt_cc::~gps_l1_ca_pvt_cc() {
@ -127,25 +127,28 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_ite
gps_navigation_message nav_msg; gps_navigation_message nav_msg;
while (d_nav_queue->try_pop(nav_msg)==true) while (d_nav_queue->try_pop(nav_msg)==true)
{ {
std::cout<<"New ephemeris record has arrived from SAT ID "<<nav_msg.d_satellite_PRN<<std::endl; std::cout<<"New ephemeris record has arrived from SAT ID "<<nav_msg.i_satellite_PRN<< " (Block " << nav_msg.satelliteBlock[nav_msg.i_satellite_PRN] << ")" << std::endl;
d_last_nav_msg=nav_msg; d_last_nav_msg=nav_msg;
d_ls_pvt->d_ephemeris[nav_msg.d_channel_ID]=nav_msg; d_ls_pvt->d_ephemeris[nav_msg.i_channel_ID]=nav_msg;
// **** update pseudoranges clock **** // **** update pseudoranges clock ****
if (nav_msg.d_satellite_PRN==gnss_pseudoranges_iter->second.SV_ID) if (nav_msg.i_satellite_PRN==gnss_pseudoranges_iter->second.SV_ID)
{ {
d_ephemeris_clock_s=d_last_nav_msg.d_TOW; d_ephemeris_clock_s=d_last_nav_msg.d_TOW;
d_ephemeris_timestamp_ms=d_last_nav_msg.d_subframe1_timestamp_ms; d_ephemeris_timestamp_ms=d_last_nav_msg.d_subframe1_timestamp_ms;
} }
// **** write ephemeris to RINES NAV file // write ephemeris to RINES NAV file, if created. Put here another condition to separate anotations
//d_rinex_printer.LogRinex2Nav(nav_msg); if(b_rinex_header_writen)
{
rp->LogRinexNav(rp->navFile, d_last_nav_msg);
}
} }
// ############ 2. COMPUTE THE PVT ################################ // ############ 2. COMPUTE THE PVT ################################
// write the pseudoranges to RINEX OBS file // write the pseudoranges to RINEX OBS file
// 1- need a valid clock // 1- need a valid clock
if (d_ephemeris_clock_s>0 and d_last_nav_msg.d_satellite_PRN>0) if (d_ephemeris_clock_s>0 and d_last_nav_msg.i_satellite_PRN>0)
{ {
//d_rinex_printer.LogRinex2Obs(d_last_nav_msg,d_ephemeris_clock_s+((double)pseudoranges_timestamp_ms-d_ephemeris_timestamp_ms)/1000.0,pseudoranges); //d_Rinex_Printer.LogRinex2Obs(d_last_nav_msg,d_ephemeris_clock_s+((double)pseudoranges_timestamp_ms-d_ephemeris_timestamp_ms)/1000.0,pseudoranges);
// compute on the fly PVT solution // compute on the fly PVT solution
//std::cout<<"diff_clock_ephemeris="<<(gnss_pseudoranges_iter->second.timestamp_ms-d_ephemeris_timestamp_ms)/1000.0<<"\r\n"; //std::cout<<"diff_clock_ephemeris="<<(gnss_pseudoranges_iter->second.timestamp_ms-d_ephemeris_timestamp_ms)/1000.0<<"\r\n";
if (d_ls_pvt->get_PVT(gnss_pseudoranges_map, if (d_ls_pvt->get_PVT(gnss_pseudoranges_map,
@ -155,11 +158,11 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_ite
d_kml_dump.print_position(d_ls_pvt,d_flag_averaging); d_kml_dump.print_position(d_ls_pvt,d_flag_averaging);
if (!b_rinex_header_writen) // & we have utc data in nav message! if (!b_rinex_header_writen) // & we have utc data in nav message!
{ {
// rinex_printer rinex_printer(d_last_nav_msg); rp->RinexNavHeader(rp->navFile, d_last_nav_msg);
rp->Rinex2NavHeader(rp->navFile, d_last_nav_msg); rp->RinexObsHeader(rp->obsFile, d_last_nav_msg);
rp->Rinex2ObsHeader(rp->obsFile, d_last_nav_msg);
b_rinex_header_writen=true; // do not write header anymore b_rinex_header_writen=true; // do not write header anymore
} }
} }
} }

View File

@ -4,7 +4,7 @@
* \author Javier Arribas, 2011. jarribas(at)cttc.es * \author Javier Arribas, 2011. jarribas(at)cttc.es
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -39,7 +39,7 @@
#include "concurrent_queue.h" #include "concurrent_queue.h"
#include "gps_navigation_message.h" #include "gps_navigation_message.h"
#include "kml_printer.h" #include "kml_printer.h"
#include "rinex_2_1_printer.h" #include "rinex_printer.h"
#include "gps_l1_ca_ls_pvt.h" #include "gps_l1_ca_ls_pvt.h"
#include "GPS_L1_CA.h" #include "GPS_L1_CA.h"
@ -66,7 +66,7 @@ private:
bool b_rinex_header_writen; bool b_rinex_header_writen;
//std::ofstream Rinex_Nav_File; //std::ofstream Rinex_Nav_File;
//std::ofstream Rinex_Obs_File; //std::ofstream Rinex_Obs_File;
rinex_printer *rp; Rinex_Printer *rp;
unsigned int d_nchannels; unsigned int d_nchannels;
@ -86,7 +86,7 @@ private:
double d_ephemeris_clock_s; double d_ephemeris_clock_s;
double d_ephemeris_timestamp_ms; double d_ephemeris_timestamp_ms;
gps_l1_ca_ls_pvt *d_ls_pvt; gps_l1_ca_ls_pvt *d_ls_pvt;
//rinex_printer d_rinex_printer; // RINEX printer class
public: public:

View File

@ -220,7 +220,7 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,gnss_pseudorange> gnss_pseudoranges_
{ {
if (d_ephemeris[i].satellite_validation()==true) if (d_ephemeris[i].satellite_validation()==true)
{ {
gnss_pseudoranges_iter=gnss_pseudoranges_map.find(d_ephemeris[i].d_satellite_PRN); gnss_pseudoranges_iter=gnss_pseudoranges_map.find(d_ephemeris[i].i_satellite_PRN);
if (gnss_pseudoranges_iter!=gnss_pseudoranges_map.end()) if (gnss_pseudoranges_iter!=gnss_pseudoranges_map.end())
{ {
/*! /*!
@ -242,7 +242,7 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,gnss_pseudorange> gnss_pseudoranges_
satpos(0,i)=d_ephemeris[i].d_satpos_X; satpos(0,i)=d_ephemeris[i].d_satpos_X;
satpos(1,i)=d_ephemeris[i].d_satpos_Y; satpos(1,i)=d_ephemeris[i].d_satpos_Y;
satpos(2,i)=d_ephemeris[i].d_satpos_Z; satpos(2,i)=d_ephemeris[i].d_satpos_Z;
LOG_AT_LEVEL(INFO)<<"ECEF satellite SV ID="<<d_ephemeris[i].d_satellite_PRN<<" X="<<d_ephemeris[i].d_satpos_X LOG_AT_LEVEL(INFO)<<"ECEF satellite SV ID="<<d_ephemeris[i].i_satellite_PRN<<" X="<<d_ephemeris[i].d_satpos_X
<<" [m] Y="<<d_ephemeris[i].d_satpos_Y<<" [m] Z="<<d_ephemeris[i].d_satpos_Z<<" [m]\r\n"; <<" [m] Y="<<d_ephemeris[i].d_satpos_Y<<" [m] Z="<<d_ephemeris[i].d_satpos_Z<<" [m]\r\n";
obs(i)=gnss_pseudoranges_iter->second.pseudorange_m+d_ephemeris[i].d_satClkCorr*GPS_C_m_s; obs(i)=gnss_pseudoranges_iter->second.pseudorange_m+d_ephemeris[i].d_satClkCorr*GPS_C_m_s;
valid_obs++; valid_obs++;

View File

@ -1,5 +1,5 @@
project : build-dir ../../../../build ; project : build-dir ../../../../build ;
obj rinex_2_1_printer : rinex_2_1_printer.cc ; obj rinex_printer : rinex_printer.cc ;
obj gps_l1_ca_ls_pvt : gps_l1_ca_ls_pvt.cc ; obj gps_l1_ca_ls_pvt : gps_l1_ca_ls_pvt.cc ;
obj kml_printer : kml_printer.cc ; obj kml_printer : kml_printer.cc ;

View File

@ -1,6 +1,6 @@
/*! /*!
* \file rinex_2_1_printer.cc (temporal name) * \file rinex_printer.cc
* \brief Implementation of a RINEX 3.01 printer * \brief Implementation of a RINEX 2.11 / 3.01 printer
* See http://igscb.jpl.nasa.gov/igscb/data/format/rinex301.pdf * See http://igscb.jpl.nasa.gov/igscb/data/format/rinex301.pdf
* \author Carles Fernandez Prades, 2011. cfernandez(at)cttc.es * \author Carles Fernandez Prades, 2011. cfernandez(at)cttc.es
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
@ -28,7 +28,7 @@
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*/ */
#include "rinex_2_1_printer.h" #include "rinex_printer.h"
#include "gps_navigation_message.h" #include "gps_navigation_message.h"
#include <ostream> #include <ostream>
#include <fstream> #include <fstream>
@ -49,12 +49,15 @@
using google::LogMessage; using google::LogMessage;
DEFINE_string(RINEX_version, "3.01",
"Specifies the RINEX version (2.11 or 3.01)");
rinex_printer::rinex_printer()
Rinex_Printer::Rinex_Printer()
{ {
rinex_printer::navFile.open(rinex_printer::createFilename("RINEX_FILE_TYPE_GPS_NAV"), std::ios::out | std::ios::app); Rinex_Printer::navFile.open(Rinex_Printer::createFilename("RINEX_FILE_TYPE_GPS_NAV"), std::ios::out | std::ios::app);
rinex_printer::obsFile.open(rinex_printer::createFilename("RINEX_FILE_TYPE_OBS"), std::ios::out | std::ios::app); Rinex_Printer::obsFile.open(Rinex_Printer::createFilename("RINEX_FILE_TYPE_OBS"), std::ios::out | std::ios::app);
satelliteSystem["GPS"]="G"; satelliteSystem["GPS"]="G";
satelliteSystem["GLONASS"]="R"; satelliteSystem["GLONASS"]="R";
@ -123,21 +126,42 @@ rinex_printer::rinex_printer()
observationType["DOPPLER"]="D"; observationType["DOPPLER"]="D";
observationType["SIGNAL_STRENGTH"]="S"; observationType["SIGNAL_STRENGTH"]="S";
if (FLAGS_RINEX_version.compare("3.01") == 0 )
{
version = 3;
stringVersion="3.01";
}
else if (FLAGS_RINEX_version.compare("2.11") == 0 )
{
version = 2;
stringVersion="2.10";
}
else if (FLAGS_RINEX_version.compare("2.10") == 0 )
{
version = 2;
stringVersion="2.10";
}
else
{
LOG_AT_LEVEL(ERROR) << "Unknown RINEX version " << FLAGS_RINEX_version << " (must be 2.11 or 3.01)" << std::endl;
}
} }
rinex_printer::~rinex_printer() Rinex_Printer::~Rinex_Printer()
{ {
// close RINEX files // close RINEX files
rinex_printer::navFile.close(); Rinex_Printer::navFile.close();
rinex_printer::obsFile.close(); Rinex_Printer::obsFile.close();
} }
void rinex_printer::lengthCheck(std::string line) void Rinex_Printer::lengthCheck(std::string line)
{ {
if (line.length() != 80) if (line.length() != 80)
{ {
@ -149,7 +173,7 @@ void rinex_printer::lengthCheck(std::string line)
} }
std::string rinex_printer::createFilename(std::string type){ std::string Rinex_Printer::createFilename(std::string type){
const std::string stationName = "GSDR"; // 4-character station name designator const std::string stationName = "GSDR"; // 4-character station name designator
boost::gregorian::date today = boost::gregorian::day_clock::local_day(); boost::gregorian::date today = boost::gregorian::day_clock::local_day();
const int dayOfTheYear = today.day_of_year(); const int dayOfTheYear = today.day_of_year();
@ -159,7 +183,6 @@ std::string rinex_printer::createFilename(std::string type){
strm0 << dayOfTheYear; strm0 << dayOfTheYear;
std::string dayOfTheYearTag=strm0.str(); std::string dayOfTheYearTag=strm0.str();
std::map<std::string, std::string> fileType; std::map<std::string, std::string> fileType;
fileType.insert(std::pair<std::string, std::string>("RINEX_FILE_TYPE_OBS","O")); // O - Observation file. fileType.insert(std::pair<std::string, std::string>("RINEX_FILE_TYPE_OBS","O")); // O - Observation file.
fileType.insert(std::pair<std::string, std::string>("RINEX_FILE_TYPE_GPS_NAV","N")); // N - GPS navigation message file. fileType.insert(std::pair<std::string, std::string>("RINEX_FILE_TYPE_GPS_NAV","N")); // N - GPS navigation message file.
@ -179,7 +202,6 @@ std::string rinex_printer::createFilename(std::string type){
strm << local_hour; strm << local_hour;
std::map<std::string, std::string> Hmap; std::map<std::string, std::string> Hmap;
Hmap.insert(std::pair<std::string, std::string>("0","a")); Hmap.insert(std::pair<std::string, std::string>("0","a"));
Hmap.insert(std::pair<std::string, std::string>("1","b")); Hmap.insert(std::pair<std::string, std::string>("1","b"));
Hmap.insert(std::pair<std::string, std::string>("2","c")); Hmap.insert(std::pair<std::string, std::string>("2","c"));
@ -226,113 +248,204 @@ std::string rinex_printer::createFilename(std::string type){
} }
std::string rinex_printer::getLocalTime() std::string Rinex_Printer::getLocalTime()
{ {
std::string line; std::string line;
line +=std::string("GNSS-SDR"); line +=std::string("GNSS-SDR");
line +=std::string(12,' '); line +=std::string(12,' ');
line += rinex_printer::leftJustify("CTTC", 20);//put a flag to let the user change this line += Rinex_Printer::leftJustify("CTTC", 20); //put a flag to let the user change this
boost::gregorian::date today = boost::gregorian::day_clock::local_day(); boost::gregorian::date today = boost::gregorian::day_clock::local_day();
line +=boost::gregorian::to_iso_string(today);
line +=std::string(1,' ');
boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone("UTC")); boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone("UTC"));
boost::local_time::local_date_time pt = boost::local_time::local_sec_clock::local_time(zone); boost::local_time::local_date_time pt = boost::local_time::local_sec_clock::local_time(zone);
tm pt_tm=boost::local_time::to_tm(pt); tm pt_tm=boost::local_time::to_tm(pt);
std::stringstream strm0; std::stringstream strmHour;
int utc_hour=pt_tm.tm_hour; int utc_hour=pt_tm.tm_hour;
if (utc_hour<10) strm0 << "0"; // two digits for hours if (utc_hour<10) strmHour << "0"; // two digits for hours
strm0 << utc_hour; strmHour << utc_hour;
line += strm0.str();
std::stringstream strm1; std::stringstream strmMin;
int utc_minute=pt_tm.tm_min; int utc_minute=pt_tm.tm_min;
if (utc_minute<10) strm1 << "0"; // two digits for minutes if (utc_minute<10) strmMin << "0"; // two digits for minutes
strm1 << utc_minute; strmMin << utc_minute;
line += strm1.str();
if (version == 2)
{
int day= pt_tm.tm_mday;
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(day),2);
line += std::string("-");
std::map<int, std::string> months;
months[0]="JAN";
months[1]="FEB";
months[2]="MAR";
months[3]="APR";
months[4]="MAY";
months[5]="JUN";
months[6]="JUL";
months[7]="AUG";
months[8]="SEP";
months[9]="OCT";
months[10]="NOV";
months[11]="DEC";
line += months[pt_tm.tm_mon];
line += std::string("-");
line += boost::lexical_cast<std::string>(pt_tm.tm_year-100);
line +=std::string(1,' ');
line += strmHour.str();
line +=std::string(":");
line += strmMin.str();
line +=std::string(5,' ');
}
if (version == 3)
{
line +=std::string(1,' ');
line +=boost::gregorian::to_iso_string(today);
line += strmHour.str();
line += strmMin.str();
std::stringstream strm2;
int utc_seconds=pt_tm.tm_sec;
if (utc_seconds<10) strm2 << "0"; // two digits for seconds
strm2 << utc_seconds;
line += strm2.str();
line +=std::string(1,' ');
line +=std::string("UTC");
line +=std::string(1,' ');
}
std::stringstream strm2;
int utc_seconds=pt_tm.tm_sec;
if (utc_seconds<10) strm2 << "0"; // two digits for seconds
strm2 << utc_seconds;
line += strm2.str();
line +=std::string(1,' ');
line +=std::string("UTC");
line +=std::string(1,' ');
return line; return line;
} }
void rinex_printer::Rinex2NavHeader(std::ofstream& out, gps_navigation_message nav_msg) void Rinex_Printer::RinexNavHeader(std::ofstream& out, gps_navigation_message nav_msg)
{ {
std::string line; std::string line;
// -------- Line 1 // -------- Line 1
std::string version="3.01";
line = std::string(5,' '); line = std::string(5,' ');
line += version; line += stringVersion;
line += std::string(11,' '); line += std::string(11,' ');
line += std::string("N: GNSS NAV DATA");
line += std::string(4,' ');
//! \todo Add here other systems...
line += std::string("G: GPS");
line += std::string(14,' ');
// ...
line += std::string("RINEX VERSION / TYPE");
rinex_printer::lengthCheck(line);
if (version == 2)
{
line += std::string("N: GPS NAV DATA");
line += std::string(25,' ');
}
if (version == 3 )
{
line += std::string("N: GNSS NAV DATA");
line += std::string(4,' ');
//! \todo Add here other systems...
line += std::string("G: GPS");
line += std::string(14,' ');
// ...
}
line += std::string("RINEX VERSION / TYPE");
Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- Line 2 // -------- Line 2
line.clear(); line.clear();
line += rinex_printer::getLocalTime(); line += Rinex_Printer::getLocalTime();
line += std::string("PGM / RUN BY / DATE"); line += std::string("PGM / RUN BY / DATE");
line += std::string(1,' '); line += std::string(1,' ');
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- Line 3 // -------- Line 3
line.clear(); line.clear();
line += rinex_printer::leftJustify("GPS NAVIGATION MESSAGE FILE GENERATED BY GNSS-SDR",60); line += Rinex_Printer::leftJustify("GPS NAVIGATION MESSAGE FILE GENERATED BY GNSS-SDR",60);
line += rinex_printer::leftJustify("COMMENT",20); line += Rinex_Printer::leftJustify("COMMENT",20);
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- Line 4 ionospheric info
line.clear();
line += std::string("GPSA");
line += std::string(1,' ');
line += rinex_printer::rightJustify(rinex_printer::doub2for(nav_msg.d_alpha0, 12, 2),12);
line += rinex_printer::rightJustify(rinex_printer::doub2for(nav_msg.d_alpha1, 12, 2),12);
line += rinex_printer::rightJustify(rinex_printer::doub2for(nav_msg.d_alpha2, 12, 2),12);
line += rinex_printer::rightJustify(rinex_printer::doub2for(nav_msg.d_alpha3, 12, 2),12);
line += std::string(7,' ');
line += rinex_printer::leftJustify("IONOSPHERIC CORR",20);
rinex_printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- Line 5 ionospheric info
line.clear(); line.clear();
line += std::string("GPSB"); line += Rinex_Printer::leftJustify("See http://gnss-sdr.org",60);
line += std::string(1,' '); line += Rinex_Printer::leftJustify("COMMENT",20);
line += rinex_printer::rightJustify(rinex_printer::doub2for(nav_msg.d_beta0, 12, 2),12); Rinex_Printer::lengthCheck(line);
line += rinex_printer::rightJustify(rinex_printer::doub2for(nav_msg.d_beta1, 12, 2),12); out << line << std::endl;
line += rinex_printer::rightJustify(rinex_printer::doub2for(nav_msg.d_beta2, 12, 2),12); // -------- Line ionospheric info 1
line += rinex_printer::rightJustify(rinex_printer::doub2for(nav_msg.d_beta3, 12, 2),12); line.clear();
line += std::string(7,' '); if (version == 2)
line += rinex_printer::leftJustify("IONOSPHERIC CORR",20); {
rinex_printer::lengthCheck(line); line += std::string(2,' ');
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_alpha0, 10, 2),12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_alpha1, 10, 2),12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_alpha2, 10, 2),12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_alpha3, 10, 2),12);
line += std::string(10,' ');
line += Rinex_Printer::leftJustify("ION ALPHA",20);
}
if (version == 3)
{
line += std::string("GPSA");
line += std::string(1,' ');
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_alpha0, 10, 2),12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_alpha1, 10, 2),12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_alpha2, 10, 2),12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.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 1
line.clear();
if (version == 2)
{
line += std::string(2,' ');
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_beta0, 10, 2),12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_beta1, 10, 2),12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_beta2, 10, 2),12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_beta3, 10, 2),12);
line += std::string(10,' ');
line += Rinex_Printer::leftJustify("ION BETA",20);
}
if (version == 3)
{
line += std::string("GPSB");
line += std::string(1,' ');
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_beta0, 10, 2),12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_beta1, 10, 2),12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_beta2, 10, 2),12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(nav_msg.d_beta3, 10, 2),12);
line += std::string(7,' ');
line += Rinex_Printer::leftJustify("IONOSPHERIC CORR",20);
}
Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- Line 5 system time correction // -------- Line 5 system time correction
line.clear(); line.clear();
line += std::string("GPUT"); if (version == 2)
line += std::string(1,' '); {
line += rinex_printer::doub2for(nav_msg.d_A0, 17, 2); line += std::string(4,' ');
line += rinex_printer::doub2for(nav_msg.d_A1, 16, 2); line += Rinex_Printer::doub2for(nav_msg.d_A0, 18, 2);
line += rinex_printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.d_t_OT),7); line += std::string(1,' ');
line += rinex_printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.i_WN_T),5); line += Rinex_Printer::doub2for(nav_msg.d_A1, 18, 2);
/* if ( SBAS ) line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.d_t_OT),9);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.i_WN_T),9);
line += std::string(1,' ');
line += Rinex_Printer::leftJustify("DELTA-UTC: A0,A1,T,W",20);
}
if (version == 3)
{
line += std::string("GPUT");
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_A0, 17, 2);
line += Rinex_Printer::doub2for(nav_msg.d_A1, 16, 2);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.d_t_OT),7);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.i_WN_T),5);
/* if ( SBAS )
{ {
line += string(1, ' '); line += string(1, ' ');
line += leftJustify(asString(d_t_OT_SBAS),5); line += leftJustify(asString(d_t_OT_SBAS),5);
@ -341,31 +454,39 @@ void rinex_printer::Rinex2NavHeader(std::ofstream& out, gps_navigation_message n
line += string(1, ' '); line += string(1, ' ');
} }
else else
*/ */
line += std::string(10, ' '); line += std::string(10, ' ');
line += rinex_printer::leftJustify("TIME SYSTEM CORR",20); line += Rinex_Printer::leftJustify("TIME SYSTEM CORR",20);
rinex_printer::lengthCheck(line); }
Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- Line 6 leap seconds // -------- Line 6 leap seconds
// For leap second information, see http://www.endruntechnologies.com/leap.htm // For leap second information, see http://www.endruntechnologies.com/leap.htm
line.clear(); line.clear();
line += rinex_printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.d_DeltaT_LS),6); line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.d_DeltaT_LS),6);
line += rinex_printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.d_DeltaT_LSF),6); if (version == 2)
line += rinex_printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.i_WN_LSF),6); {
line += rinex_printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.i_DN),6); line += std::string(54,' ');
line += std::string(36, ' '); }
line += rinex_printer::leftJustify("LEAP SECONDS",20); if (version == 3)
rinex_printer::lengthCheck(line); {
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.d_DeltaT_LSF),6);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.i_WN_LSF),6);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.i_DN),6);
line += std::string(36, ' ');
}
line += Rinex_Printer::leftJustify("LEAP SECONDS",20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- End of Header // -------- End of Header
line.clear(); line.clear();
line +=std::string(60,' '); line +=std::string(60,' ');
line += rinex_printer::leftJustify("END OF HEADER",20); line += Rinex_Printer::leftJustify("END OF HEADER",20);
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
} }
@ -378,100 +499,346 @@ void rinex_printer::Rinex2NavHeader(std::ofstream& out, gps_navigation_message n
void rinex_printer::LogRinex2Nav(std::ofstream& out, gps_navigation_message nav_msg){ void Rinex_Printer::LogRinexNav(std::ofstream& out, gps_navigation_message nav_msg)
{
/* std::string line;
if(fp_rin2 != NULL)
{
//preparacio lines de efemerides per imprimir!!! boost::posix_time::ptime p_utc_time = Rinex_Printer::computeTime(nav_msg);
char linia0[256],linia1[256],linia2[256],linia3[256],linia4[256],linia5[256],linia6[256],linia7[256]; std::string timestring=boost::posix_time::to_iso_string(p_utc_time);
char idef[256]; std::string month (timestring,4,2);
sprintf(idef,"%2.0d",nav_msg.d_satellite_PRN); std::string day (timestring,6,2);
std::string hour (timestring,9,2);
std::string minutes (timestring,11,2);
std::string seconds (timestring,13,2);
if (version == 2)
{
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(nav_msg.i_satellite_PRN),2);
line += std::string(1,' ');
std::string year (timestring,2,2);
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,' ');
line += seconds;
line += std::string(1,'.');
std::string decimal = std::string("0");
if (timestring.size() > 16)
{
std::string decimal (timestring,16,1);
}
line += decimal;
line += std::string(1,' ');
line += doub2for(nav_msg.d_A_f0, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(nav_msg.d_A_f0, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(nav_msg.d_A_f0, 18, 2);
line += std::string(1, ' ');
sprintf(linia0,"%19.12E%19.12E%19.12E",nav_msg.d_A_f0,nav_msg.d_A_f1,nav_msg.d_A_f2); }
if (version ==3 )
{
line += satelliteSystem["GPS"];
if (nav_msg.i_satellite_PRN < 10) line += std::string("0");
line += boost::lexical_cast<std::string>(nav_msg.i_satellite_PRN);
std::string year (timestring,0,4);
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,' ');
line += seconds;
line += std::string(1,' ');
line += doub2for(nav_msg.d_A_f0, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(nav_msg.d_A_f0, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(nav_msg.d_A_f0, 18, 2);
}
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
sprintf(linia1,"%19.12E%19.12E%19.12E%19.12E",nav_msg.d_IODE_SF2,nav_msg.d_Crs,nav_msg.d_Delta_n,nav_msg.d_M_0);
sprintf(linia2,"%19.12E%19.12E%19.12E%19.12E",nav_msg.d_Cuc,nav_msg.d_e_eccentricity,nav_msg.d_Cus,nav_msg.d_sqrt_A);
sprintf(linia3,"%19.12E%19.12E%19.12E%19.12E",nav_msg.d_Toe,nav_msg.d_Cic,nav_msg.d_OMEGA0,nav_msg.d_Cis);
sprintf(linia4,"%19.12E%19.12E%19.12E%19.12E",nav_msg.d_i_0,nav_msg.d_Crc,nav_msg.d_OMEGA,nav_msg.d_OMEGA_DOT);
sprintf(linia5,"%19.12E%19.12E%19.12E%19.12E",nav_msg.d_IDOT,0.0,nav_msg.d_GPS_week+1024.0,0.0);//CodeL2, L2pData line.clear();
sprintf(linia6,"%19.12E%19.12E%19.12E%19.12E",nav_msg.d_SV_accuracy,nav_msg.d_SV_health,nav_msg.d_TGD,nav_msg.d_IODC);
sprintf(linia7,"%19.12E%19.12E",nav_msg.d_TOW,0.0); //fit interval is set to 0
fseek(fp_rin2, fp_rin_end2, SEEK_SET); if (version == 2)
{
line += std::string(4, ' ');
}
if (version == 3)
{
line += std::string(5, ' ');
}
if (nav_msg.d_IODE_SF2 == nav_msg.d_IODE_SF3)
{
line += Rinex_Printer::doub2for(nav_msg.d_IODE_SF2, 18, 2);
}
else
{
LOG_AT_LEVEL(ERROR) << "Discontinued reception of Frame 2 and 3 " << std::endl;
}
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_Crs, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_Delta_n, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_M_0, 18, 2);
if (version == 2)
{
line += std::string(1, ' ');
}
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
fprintf(fp_rin2,"%s %s %s%s\n",idef,cad1,cad2,linia0);
fprintf(fp_rin2," %s\n",linia1);
fprintf(fp_rin2," %s\n",linia2); line.clear();
fprintf(fp_rin2," %s\n",linia3); if (version == 2)
{
line += std::string(4, ' ');
}
if (version == 3)
{
line += std::string(5, ' ');
}
line += Rinex_Printer::doub2for(nav_msg.d_Cuc, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_e_eccentricity, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_Cus, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_sqrt_A, 18, 2);
if (version == 2)
{
line += std::string(1, ' ');
}
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
fprintf(fp_rin2," %s\n",linia4);
fprintf(fp_rin2," %s\n",linia5);
fprintf(fp_rin2," %s\n",linia6); line.clear();
fprintf(fp_rin2," %s\n",linia7); if (version == 2)
fp_rin_end2 = ftell(fp_rin2); {
}*/ line += std::string(4, ' ');
}
if (version == 3)
{
line += std::string(5, ' ');
}
line += Rinex_Printer::doub2for(nav_msg.d_Toe, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_Cic, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_OMEGA0, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_Cis, 18, 2);
if (version == 2)
{
line += std::string(1, ' ');
}
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
line.clear();
if (version == 2)
{
line += std::string(4, ' ');
}
if (version == 3)
{
line += std::string(5, ' ');
}
line += Rinex_Printer::doub2for(nav_msg.d_i_0, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_Crc, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_OMEGA, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_OMEGA_DOT, 18, 2);
if (version == 2)
{
line += std::string(1, ' ');
}
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
line.clear();
if (version == 2)
{
line += std::string(4, ' ');
}
if (version == 3)
{
line += std::string(5, ' ');
}
line += Rinex_Printer::doub2for(nav_msg.d_IDOT, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for((double)(nav_msg.i_code_on_L2), 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for((double)(nav_msg.i_code_on_L2), 18, 2);
line += std::string(1,' ');
double GPS_week_continuous_number = (double)(nav_msg.i_GPS_week+1024); // valid until April 7, 2019 (check http://www.colorado.edu/geography/gcraft/notes/gps/gpseow.htm)
line += Rinex_Printer::doub2for(GPS_week_continuous_number, 18, 2);
if (version == 2)
{
line += std::string(1, ' ');
}
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
line.clear();
if (version == 2)
{
line += std::string(4, ' ');
}
if (version == 3)
{
line += std::string(5, ' ');
}
line += Rinex_Printer::doub2for((double)(nav_msg.i_SV_accuracy), 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for((double)(nav_msg.i_SV_health), 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_TGD, 18, 2);
line += std::string(1,' ');
line += Rinex_Printer::doub2for(nav_msg.d_IODC, 18, 2);
if (version == 2)
{
line += std::string(1, ' ');
}
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
line.clear();
if (version == 2)
{
line += std::string(4, ' ');
}
if (version == 3)
{
line += std::string(5, ' ');
}
line += Rinex_Printer::doub2for(nav_msg.d_TOW, 18, 2);
line += std::string(1,' ');
double curve_fit_interval = 4;
if (nav_msg.satelliteBlock[nav_msg.i_satellite_PRN].compare("IIA"))
{
// Block II/IIA (Table 20-XI IS-GPS-200E )
if ( (nav_msg.d_IODC > 239) && (nav_msg.d_IODC < 248)) curve_fit_interval=8;
if ( ( (nav_msg.d_IODC > 247) && (nav_msg.d_IODC < 256)) || (nav_msg.d_IODC == 496) ) curve_fit_interval=14;
if ( (nav_msg.d_IODC > 496) && (nav_msg.d_IODC < 504)) curve_fit_interval=26;
if ( (nav_msg.d_IODC > 503) && (nav_msg.d_IODC < 511)) curve_fit_interval=50;
if ( ( (nav_msg.d_IODC > 751) && (nav_msg.d_IODC < 757)) || (nav_msg.d_IODC == 511) ) curve_fit_interval=74;
if ( (nav_msg.d_IODC == 757)) curve_fit_interval=98;
}
// Block IIR/IIR-M/IIF/IIIA (Table 20-XII IS-GPS-200E )
if ((nav_msg.satelliteBlock[nav_msg.i_satellite_PRN].compare("IIR") == 0) ||
(nav_msg.satelliteBlock[nav_msg.i_satellite_PRN].compare("IIR-M") == 0) ||
(nav_msg.satelliteBlock[nav_msg.i_satellite_PRN].compare("IIF") == 0) ||
(nav_msg.satelliteBlock[nav_msg.i_satellite_PRN].compare("IIIA") == 0) )
{
if ( (nav_msg.d_IODC > 239) && (nav_msg.d_IODC < 248)) curve_fit_interval=8;
if ( ( (nav_msg.d_IODC > 247) && (nav_msg.d_IODC < 256)) || (nav_msg.d_IODC == 496) ) curve_fit_interval=14;
if ( ( (nav_msg.d_IODC > 496) && (nav_msg.d_IODC < 504)) ||( (nav_msg.d_IODC > 1020) && (nav_msg.d_IODC < 1024)) ) curve_fit_interval=26;
}
line += Rinex_Printer::doub2for(curve_fit_interval, 18, 2);
line += std::string(1,' ');
line += std::string(18,' '); // spare
line += std::string(1,' ');
line += std::string(18,' '); // spare
if (version == 2)
{
line += std::string(1, ' ');
}
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
} }
void rinex_printer::Rinex2ObsHeader(std::ofstream& out, gps_navigation_message nav_msg) void Rinex_Printer::RinexObsHeader(std::ofstream& out, gps_navigation_message nav_msg)
{ {
std::string line; std::string line;
// -------- Line 1 // -------- Line 1
std::string version="3.01";
line = std::string(5,' '); line = std::string(5,' ');
line += version; line += stringVersion;
line +=std::string(11,' '); line +=std::string(11,' ');
line += rinex_printer::leftJustify("OBSERVATION DATA",20); line += Rinex_Printer::leftJustify("OBSERVATION DATA",20);
line +=satelliteSystem["GPS"]; line +=satelliteSystem["GPS"];
line +=std::string(19,' '); line +=std::string(19,' ');
line +=std::string("RINEX VERSION / TYPE"); line +=std::string("RINEX VERSION / TYPE");
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- Line 2 // -------- Line 2
line.clear(); line.clear();
line += rinex_printer::leftJustify("G = GPS R = GLONASS E = GALILEO S = GEO M = MIXED",60); line += Rinex_Printer::leftJustify("G = GPS R = GLONASS E = GALILEO S = GEO M = MIXED",60);
line += rinex_printer::leftJustify("COMMENT",20); line += Rinex_Printer::leftJustify("COMMENT",20);
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- Line 3 // -------- Line 3
line.clear(); line.clear();
line += rinex_printer::getLocalTime(); line += Rinex_Printer::getLocalTime();
line +=std::string("PGM / RUN BY / DATE"); line +=std::string("PGM / RUN BY / DATE");
line +=std::string(1,' '); line +=std::string(1,' ');
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- Line 4 // -------- Line 4
line.clear(); line.clear();
line += rinex_printer::leftJustify("GPS OBSERVATION DATA FILE GENERATED BY GNSS-SDR",60); line += Rinex_Printer::leftJustify("GPS OBSERVATION DATA FILE GENERATED BY GNSS-SDR",60);
line += rinex_printer::leftJustify("COMMENT",20); line += Rinex_Printer::leftJustify("COMMENT",20);
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- Line 5
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; out << line << std::endl;
line.clear(); line.clear();
line += rinex_printer::leftJustify("GROUND_CRAFT",20); // put a flag or a property line += Rinex_Printer::leftJustify("See http://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.clear();
line += Rinex_Printer::leftJustify("GROUND_CRAFT",20); // put a flag or a property
line +=std::string(40,' '); line +=std::string(40,' ');
line += rinex_printer::leftJustify("MARKER TYPE",20); line += Rinex_Printer::leftJustify("MARKER TYPE",20);
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
@ -479,30 +846,30 @@ void rinex_printer::Rinex2ObsHeader(std::ofstream& out, gps_navigation_message n
line.clear(); line.clear();
std::string username=getenv("USER"); std::string username=getenv("USER");
line += leftJustify(username,20); line += leftJustify(username,20);
line += rinex_printer::leftJustify("CTTC",40); // add flag and property line += Rinex_Printer::leftJustify("CTTC",40); // add flag and property
line += rinex_printer::leftJustify("OBSERVER / AGENCY",20); line += Rinex_Printer::leftJustify("OBSERVER / AGENCY",20);
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- Line REC / TYPE VERS // -------- Line REC / TYPE VERS
line.clear(); line.clear();
line += rinex_printer::leftJustify("GNSS-SDR",20); // add flag and property 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("Software Receiver",20); // add flag and property
//line += rinex_printer::leftJustify(google::VersionString(),20); // add flag and property //line += Rinex_Printer::leftJustify(google::VersionString(),20); // add flag and property
line += rinex_printer::leftJustify("0.1",20); line += Rinex_Printer::leftJustify("0.1",20);
line += rinex_printer::leftJustify("REC # / TYPE / VERS",20); line += Rinex_Printer::leftJustify("REC # / TYPE / VERS",20);
lengthCheck(line); lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- ANTENNA TYPE // -------- ANTENNA TYPE
line.clear(); line.clear();
line += rinex_printer::leftJustify("Antenna number",20); // add flag and property line += Rinex_Printer::leftJustify("Antenna number",20); // add flag and property
line += rinex_printer::leftJustify("Antenna type",20); // add flag and property line += Rinex_Printer::leftJustify("Antenna type",20); // add flag and property
line +=std::string(20,' '); line +=std::string(20,' ');
line += rinex_printer::leftJustify("ANT # / TYPE",20); line += Rinex_Printer::leftJustify("ANT # / TYPE",20);
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- APPROX POSITION (optional for moving platforms) // -------- APPROX POSITION (optional for moving platforms)
@ -514,12 +881,12 @@ void rinex_printer::Rinex2ObsHeader(std::ofstream& out, gps_navigation_message n
double antena_e=0.0; double antena_e=0.0;
double antena_n=0.0; double antena_n=0.0;
line.clear(); line.clear();
line = rinex_printer::rightJustify(rinex_printer::asString(antena_h, 4), 14); 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_e, 4), 14);
line += rinex_printer::rightJustify(rinex_printer::asString(antena_n, 4), 14); line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_n, 4), 14);
line += std::string(18, ' '); line += std::string(18, ' ');
line += rinex_printer::leftJustify("ANTENNA: DELTA H/E/N",20); line += Rinex_Printer::leftJustify("ANTENNA: DELTA H/E/N",20);
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
@ -532,7 +899,7 @@ void rinex_printer::Rinex2ObsHeader(std::ofstream& out, gps_navigation_message n
int numberObservations=2; // Count the number of available types of observable in the system int numberObservations=2; // Count the number of available types of observable in the system
std::stringstream strm; std::stringstream strm;
strm << numberObservations; strm << numberObservations;
line += rinex_printer::rightJustify(strm.str(),3); line += Rinex_Printer::rightJustify(strm.str(),3);
// per type of observation // per type of observation
line += std::string(1,' '); line += std::string(1,' ');
line += observationType["PSEUDORANGE"]; line += observationType["PSEUDORANGE"];
@ -542,21 +909,21 @@ void rinex_printer::Rinex2ObsHeader(std::ofstream& out, gps_navigation_message n
line += observationCode["GPS_L1_CA"]; line += observationCode["GPS_L1_CA"];
line +=std::string(60-line.size(),' '); line +=std::string(60-line.size(),' ');
line += rinex_printer::leftJustify("SYS / # / OBS TYPES",20); line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES",20);
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- Signal Strength units // -------- Signal Strength units
line.clear(); line.clear();
line += rinex_printer::leftJustify("DBHZ",20); line += Rinex_Printer::leftJustify("DBHZ",20);
line +=std::string(40,' '); line +=std::string(40,' ');
line += rinex_printer::leftJustify("SIGNAL STRENGTH UNIT",20); line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT",20);
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- TIME OF FIRST OBS // -------- TIME OF FIRST OBS
line.clear(); line.clear();
boost::posix_time::ptime p_utc_time = rinex_printer::computeTime(nav_msg); boost::posix_time::ptime p_utc_time = Rinex_Printer::computeTime(nav_msg);
std::string timestring=boost::posix_time::to_iso_string(p_utc_time); std::string timestring=boost::posix_time::to_iso_string(p_utc_time);
std::string year (timestring,0,4); std::string year (timestring,0,4);
std::string month (timestring,4,2); std::string month (timestring,4,2);
@ -573,8 +940,8 @@ void rinex_printer::Rinex2ObsHeader(std::ofstream& out, gps_navigation_message n
line += rightJustify(asString(seconds,7), 13); line += rightJustify(asString(seconds,7), 13);
line += rightJustify(std::string("GPS"), 8); line += rightJustify(std::string("GPS"), 8);
line +=std::string(9,' '); line +=std::string(9,' ');
line += rinex_printer::leftJustify("TIME OF FIRST OBS",20); line += Rinex_Printer::leftJustify("TIME OF FIRST OBS",20);
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
// -------- SYS /PHASE SHIFTS // -------- SYS /PHASE SHIFTS
@ -582,15 +949,15 @@ void rinex_printer::Rinex2ObsHeader(std::ofstream& out, gps_navigation_message n
// -------- end of header // -------- end of header
line.clear(); line.clear();
line +=std::string(60,' '); line +=std::string(60,' ');
line += rinex_printer::leftJustify("END OF HEADER",20); line += Rinex_Printer::leftJustify("END OF HEADER",20);
rinex_printer::lengthCheck(line); Rinex_Printer::lengthCheck(line);
out << line << std::endl; out << line << std::endl;
} }
void rinex_printer::LogRinex2Obs(gps_navigation_message nav_msg,double pseudoranges_clock, std::map<int,float> pseudoranges) void Rinex_Printer::LogRinexObs(gps_navigation_message nav_msg,double pseudoranges_clock, std::map<int,float> pseudoranges)
{ {
/* int ss; /* int ss;
char sat_vis[36]; char sat_vis[36];
@ -700,7 +1067,7 @@ void rinex_printer::LogRinex2Obs(gps_navigation_message nav_msg,double pseudoran
int rinex_printer::signalStrength(double snr) int Rinex_Printer::signalStrength(double snr)
{ {
int ss; int ss;
@ -709,7 +1076,7 @@ int rinex_printer::signalStrength(double snr)
} }
boost::posix_time::ptime rinex_printer::computeTime(gps_navigation_message nav_msg) boost::posix_time::ptime Rinex_Printer::computeTime(gps_navigation_message nav_msg)
{ {
// if we are processing a file -> wait to leap second to resolve the ambiguity else take the week from the local system time // if we are processing a file -> wait to leap second to resolve the ambiguity else take the week from the local system time
//: idea resolve the ambiguity with the leap second http://www.colorado.edu/geography/gcraft/notes/gps/gpseow.htm //: idea resolve the ambiguity with the leap second http://www.colorado.edu/geography/gcraft/notes/gps/gpseow.htm

View File

@ -1,7 +1,27 @@
/*! /*!
* \file rinex_2_1_printer.h (temporal name) * \file rinex_printer.h
* \brief Interface of a RINEX 3.01 printer * \brief Interface of a RINEX 2.11 / 3.01 printer
* See http://igscb.jpl.nasa.gov/igscb/data/format/rinex301.pdf * See http://igscb.jpl.nasa.gov/igscb/data/format/rinex301.pdf
*
* Receiver Independent EXchange Format (RINEX):
* The first proposal for the Receiver Independent Exchange Format RINEX
* was developed by the Astronomical Institute of the University of Berne
* for the easy exchange of the GPS data to be collected during the large
* European GPS campaign EUREF 89, which involved more than 60 GPS receivers
* of 4 different manufacturers.
* The governing aspect during the development was the fact that most geodetic
* processing software for GPS data use a well-defined set of observables:
* 1) The carrier-phase measurement at one or both carriers (actually being a
* measurement on the beat frequency between the received carrier of the
* satellite signal and a receiver-generated reference frequency).
* 2) The pseudorange (code) measuremen , equivalent to the difference
* of the time of reception (expressed in the time frame of the receiver)
* and the time of transmission (expressed in the time frame of the satellite)
* of a distinct satellite signal.
* 3) The observation time being the reading of the receiver clock at the
* instant of validity of the carrier-phase and/or the code measurements.
* Note: A collection of the formats currently used by the IGS can be found
* here: http://igscb.jpl.nasa.gov/components/formats.html
* \author Carles Fernandez Prades, 2011. cfernandez(at)cttc.es * \author Carles Fernandez Prades, 2011. cfernandez(at)cttc.es
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
@ -43,11 +63,52 @@
* \brief Class that handles the generation of Receiver * \brief Class that handles the generation of Receiver
* INdependent EXchange format (RINEX) files * INdependent EXchange format (RINEX) files
*/ */
class rinex_printer class Rinex_Printer
{ {
public:
/*!
* \brief Default constructor. Creates GPS Navigation and Observables RINEX files and their headers
*/
Rinex_Printer();
/*!
* \brief Default destructor. Closes GPS Navigation and Observables RINEX files
*/
~Rinex_Printer();
std::ofstream obsFile ;
std::ofstream navFile ;
/*!
* \brief Generates the Navigation Data header
*/
void RinexNavHeader(std::ofstream& out, gps_navigation_message nav);
/*!
* \brief Generates the Observation data header
*/
void RinexObsHeader(std::ofstream& out, gps_navigation_message nav);
boost::posix_time::ptime computeTime(gps_navigation_message nav_msg);
void LogRinexNav(std::ofstream& out, gps_navigation_message nav_msg);
void LogRinexObs(gps_navigation_message nav_msg, double interframe_seconds, std::map<int,float> pseudoranges);
std::map<std::string,std::string> satelliteSystem;
std::map<std::string,std::string> observationType;
std::map<std::string,std::string> observationCode;
std::string stringVersion; //<! RINEX version (2.11 or 3.01)
private: private:
int version ; // RINEX version (2 for 2.11 and 3 for 3.01)
/* /*
@ -176,11 +237,11 @@ private:
* produce an exponential with an E instead of a D, and always have a leading * produce an exponential with an E instead of a D, and always have a leading
* zero. For example -> 0.87654E-0004 or -0.1234E00005. * zero. For example -> 0.87654E-0004 or -0.1234E00005.
*/ */
inline std::string& sci2for(std::string& aStr, inline std::string& sci2for(std::string& aStr,
const std::string::size_type startPos = 0, const std::string::size_type startPos = 0,
const std::string::size_type length = std::string::npos, const std::string::size_type length = std::string::npos,
const std::string::size_type expLen = 3, const std::string::size_type expLen = 3,
const bool checkSwitch = true); const bool checkSwitch = true);
@ -250,50 +311,13 @@ private:
template <class X> template <class X>
inline std::string asString(const X x); inline std::string asString(const X x);
public:
/*!
* \brief Default constructor. Creates GPS Navigation and Observables RINEX files and their headers
*/
rinex_printer();
std::ofstream obsFile ;
std::ofstream navFile ;
/*!
* \brief Generates the Navigation Data header
*/
void Rinex2NavHeader(std::ofstream& out, gps_navigation_message nav);
/*!
* \brief Generates the Observation data header
*/
void Rinex2ObsHeader(std::ofstream& out, gps_navigation_message nav);
boost::posix_time::ptime computeTime(gps_navigation_message nav_msg);
/*!
* \brief Default destructor. Closes GPS Navigation and Observables RINEX files
*/
~rinex_printer();
void LogRinex2Nav(std::ofstream& out, gps_navigation_message nav_msg);
void LogRinex2Obs(gps_navigation_message nav_msg, double interframe_seconds, std::map<int,float> pseudoranges);
std::map<std::string,std::string> satelliteSystem;
std::map<std::string,std::string> observationType;
std::map<std::string,std::string> observationCode;
}; };
// Implementation of inline functions // Implementation of inline functions (modified versions from GPSTk http://www.gpstk.org)
inline std::string& rinex_printer::leftJustify(std::string& s, inline std::string& Rinex_Printer::leftJustify(std::string& s,
const std::string::size_type length, const std::string::size_type length,
const char pad) const char pad)
{ {
@ -312,7 +336,7 @@ inline std::string& rinex_printer::leftJustify(std::string& s,
// if the string is bigger than length, truncate it from the left. // if the string is bigger than length, truncate it from the left.
// otherwise, add pad characters to its left. // otherwise, add pad characters to its left.
inline std::string& rinex_printer::rightJustify(std::string& s, inline std::string& Rinex_Printer::rightJustify(std::string& s,
const std::string::size_type length, const std::string::size_type length,
const char pad) const char pad)
{ {
@ -331,7 +355,7 @@ inline std::string& rinex_printer::rightJustify(std::string& s,
inline std::string rinex_printer::doub2for(const double& d, inline std::string Rinex_Printer::doub2for(const double& d,
const std::string::size_type length, const std::string::size_type length,
const std::string::size_type expLen, const std::string::size_type expLen,
const bool checkSwitch) const bool checkSwitch)
@ -351,7 +375,7 @@ inline std::string rinex_printer::doub2for(const double& d,
} }
inline std::string rinex_printer::doub2sci(const double& d, inline std::string Rinex_Printer::doub2sci(const double& d,
const std::string::size_type length, const std::string::size_type length,
const std::string::size_type expLen, const std::string::size_type expLen,
const bool showSign, const bool showSign,
@ -381,7 +405,7 @@ inline std::string rinex_printer::doub2sci(const double& d,
return toReturn; return toReturn;
} }
inline std::string& rinex_printer::sci2for(std::string& aStr, inline std::string& Rinex_Printer::sci2for(std::string& aStr,
const std::string::size_type startPos, const std::string::size_type startPos,
const std::string::size_type length, const std::string::size_type length,
const std::string::size_type expLen, const std::string::size_type expLen,
@ -450,7 +474,7 @@ inline std::string& rinex_printer::sci2for(std::string& aStr,
} }
else else
aStr += "+"; aStr += "+";
aStr += rinex_printer::rightJustify(asString(iexp),expLen,'0'); aStr += Rinex_Printer::rightJustify(asString(iexp),expLen,'0');
} }
@ -484,7 +508,7 @@ inline std::string asString(const long double x, const std::string::size_type pr
inline std::string rinex_printer::asString(const double x, const std::string::size_type precision) inline std::string Rinex_Printer::asString(const double x, const std::string::size_type precision)
{ {
std::ostringstream ss; std::ostringstream ss;
ss << std::fixed << std::setprecision(precision) << x; ss << std::fixed << std::setprecision(precision) << x;
@ -492,7 +516,7 @@ inline std::string rinex_printer::asString(const double x, const std::string::si
} }
template<class X> template<class X>
inline std::string rinex_printer::asString(const X x) inline std::string Rinex_Printer::asString(const X x)
{ {
std::ostringstream ss; std::ostringstream ss;
ss << x; ss << x;

View File

@ -5,7 +5,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver

View File

@ -6,7 +6,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver

View File

@ -39,7 +39,7 @@
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include "concurrent_queue.h" #include "concurrent_queue.h"
#include "gps_navigation_message.h" #include "gps_navigation_message.h"
#include "rinex_2_1_printer.h" #include "rinex_printer.h"
#include "GPS_L1_CA.h" #include "GPS_L1_CA.h"
class gps_l1_ca_observables_cc; class gps_l1_ca_observables_cc;

View File

@ -6,7 +6,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -51,73 +51,80 @@ using google::LogMessage;
*/ */
gps_l1_ca_telemetry_decoder_cc_sptr gps_l1_ca_telemetry_decoder_cc_sptr
gps_l1_ca_make_telemetry_decoder_cc(unsigned int satellite, long if_freq, long fs_in, unsigned gps_l1_ca_make_telemetry_decoder_cc(unsigned int satellite, long if_freq, long fs_in, unsigned
int vector_length, gr_msg_queue_sptr queue, bool dump) { int vector_length, gr_msg_queue_sptr queue, bool dump)
{
return gps_l1_ca_telemetry_decoder_cc_sptr(new gps_l1_ca_telemetry_decoder_cc(satellite, if_freq, return gps_l1_ca_telemetry_decoder_cc_sptr(new gps_l1_ca_telemetry_decoder_cc(satellite, if_freq,
fs_in, vector_length, queue, dump)); fs_in, vector_length, queue, dump));
} }
void gps_l1_ca_telemetry_decoder_cc::forecast (int noutput_items, void gps_l1_ca_telemetry_decoder_cc::forecast (int noutput_items,
gr_vector_int &ninput_items_required){ gr_vector_int &ninput_items_required)
for (unsigned i = 0; i < 3; i++) { {
ninput_items_required[i] =d_samples_per_bit*8; //set the required sample history for (unsigned i = 0; i < 3; i++)
} {
ninput_items_required[i] =d_samples_per_bit*8; //set the required sample history
}
} }
gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(unsigned int satellite, long if_freq, long fs_in, unsigned gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(unsigned int satellite, long if_freq, long fs_in, unsigned
int vector_length, gr_msg_queue_sptr queue, bool dump) : int vector_length, gr_msg_queue_sptr queue, bool dump) :
gr_block ("gps_navigation_cc", gr_make_io_signature (5, 5, sizeof(double)), gr_block ("gps_navigation_cc", gr_make_io_signature (5, 5, sizeof(double)),
gr_make_io_signature(1, 1, sizeof(gnss_synchro))) { gr_make_io_signature(1, 1, sizeof(gnss_synchro)))
// initialize internal vars {
d_queue = queue; // initialize internal vars
d_dump = dump; d_queue = queue;
d_satellite = satellite; d_dump = dump;
d_vector_length = vector_length; d_satellite = satellite;
d_samples_per_bit=20; // it is exactly 1000*(1/50)=20 d_vector_length = vector_length;
d_fs_in=fs_in; d_samples_per_bit=20; // it is exactly 1000*(1/50)=20
d_preamble_duration_seconds=(1.0/(float)GPS_CA_TELEMETRY_RATE_BITS_SECOND)*(float)GPS_CA_PREAMBLE_LENGTH_BITS; d_fs_in=fs_in;
//std::cout<<"d_preamble_duration_seconds="<<d_preamble_duration_seconds<<"\r\n"; d_preamble_duration_seconds=(1.0/(float)GPS_CA_TELEMETRY_RATE_BITS_SECOND)*(float)GPS_CA_PREAMBLE_LENGTH_BITS;
// set the preamble //std::cout<<"d_preamble_duration_seconds="<<d_preamble_duration_seconds<<"\r\n";
unsigned short int preambles_bits[8]=GPS_PREAMBLE; // set the preamble
unsigned short int preambles_bits[8]=GPS_PREAMBLE;
memcpy((unsigned short int*)this->d_preambles_bits, (unsigned short int*)preambles_bits, 8* sizeof(unsigned short int)); memcpy((unsigned short int*)this->d_preambles_bits, (unsigned short int*)preambles_bits, 8* sizeof(unsigned short int));
// preamble bits to sampled symbols // preamble bits to sampled symbols
d_preambles_symbols=(signed int*)malloc(sizeof(signed int)*8*d_samples_per_bit); d_preambles_symbols=(signed int*)malloc(sizeof(signed int)*8*d_samples_per_bit);
int n=0; int n=0;
for (int i=0;i<8;i++) for (int i=0;i<8;i++)
{
for (unsigned int j=0;j<d_samples_per_bit;j++)
{
if (d_preambles_bits[i]==1)
{ {
d_preambles_symbols[n]=1; for (unsigned int j=0;j<d_samples_per_bit;j++)
}else{ {
d_preambles_symbols[n]=-1; if (d_preambles_bits[i]==1)
{
d_preambles_symbols[n]=1;
}
else
{
d_preambles_symbols[n]=-1;
}
n++;
}
} }
n++; d_sample_counter=0;
} d_preamble_code_phase_seconds=0;
} d_stat=0;
d_sample_counter=0; d_preamble_index=0;
d_preamble_code_phase_seconds=0; d_symbol_accumulator_counter=0;
d_stat=0; d_frame_bit_index=0;
d_preamble_index=0;
d_symbol_accumulator_counter=0;
d_frame_bit_index=0;
d_flag_frame_sync=false; d_flag_frame_sync=false;
d_GPS_frame_4bytes=0; d_GPS_frame_4bytes=0;
d_prev_GPS_frame_4bytes=0; d_prev_GPS_frame_4bytes=0;
d_flag_parity=false; d_flag_parity=false;
//set_history(d_samples_per_bit*8); // At least a history of 8 bits are needed to correlate with the preamble //set_history(d_samples_per_bit*8); // At least a history of 8 bits are needed to correlate with the preamble
} }
gps_l1_ca_telemetry_decoder_cc::~gps_l1_ca_telemetry_decoder_cc() { gps_l1_ca_telemetry_decoder_cc::~gps_l1_ca_telemetry_decoder_cc()
delete d_preambles_symbols; {
d_dump_file.close(); delete d_preambles_symbols;
d_dump_file.close();
} }
@ -125,201 +132,218 @@ gps_l1_ca_telemetry_decoder_cc::~gps_l1_ca_telemetry_decoder_cc() {
bool gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(unsigned int gpsword) bool gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(unsigned int gpsword)
{ {
unsigned int d1,d2,d3,d4,d5,d6,d7,t,parity; unsigned int d1,d2,d3,d4,d5,d6,d7,t,parity;
/* XOR as many bits in parallel as possible. The magic constants pick /* XOR as many bits in parallel as possible. The magic constants pick
up bits which are to be XOR'ed together to implement the GPS parity up bits which are to be XOR'ed together to implement the GPS parity
check algorithm described in IS-GPS-200E. This avoids lengthy shift- check algorithm described in IS-GPS-200E. This avoids lengthy shift-
and-xor loops. */ and-xor loops. */
d1 = gpsword & 0xFBFFBF00; d1 = gpsword & 0xFBFFBF00;
d2 = _lrotl(gpsword,1) & 0x07FFBF01; d2 = _lrotl(gpsword,1) & 0x07FFBF01;
d3 = _lrotl(gpsword,2) & 0xFC0F8100; d3 = _lrotl(gpsword,2) & 0xFC0F8100;
d4 = _lrotl(gpsword,3) & 0xF81FFE02; d4 = _lrotl(gpsword,3) & 0xF81FFE02;
d5 = _lrotl(gpsword,4) & 0xFC00000E; d5 = _lrotl(gpsword,4) & 0xFC00000E;
d6 = _lrotl(gpsword,5) & 0x07F00001; d6 = _lrotl(gpsword,5) & 0x07F00001;
d7 = _lrotl(gpsword,6) & 0x00003000; d7 = _lrotl(gpsword,6) & 0x00003000;
t = d1 ^ d2 ^ d3 ^ d4 ^ d5 ^ d6 ^ d7; t = d1 ^ d2 ^ d3 ^ d4 ^ d5 ^ d6 ^ d7;
// Now XOR the 5 6-bit fields together to produce the 6-bit final result. // Now XOR the 5 6-bit fields together to produce the 6-bit final result.
parity = t ^ _lrotl(t,6) ^ _lrotl(t,12) ^ _lrotl(t,18) ^ _lrotl(t,24); parity = t ^ _lrotl(t,6) ^ _lrotl(t,12) ^ _lrotl(t,18) ^ _lrotl(t,24);
parity = parity & 0x3F; parity = parity & 0x3F;
if (parity == (gpsword&0x3F)) if (parity == (gpsword&0x3F))
return(true); return(true);
else else
return(false); return(false);
} }
int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_int &ninput_items, int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) {
int corr_value=0; int corr_value=0;
int preamble_diff; int preamble_diff;
gnss_synchro gps_synchro; //structure to save the synchronization information gnss_synchro gps_synchro; //structure to save the synchronization information
gnss_synchro **out = (gnss_synchro **) &output_items[0]; gnss_synchro **out = (gnss_synchro **) &output_items[0];
d_sample_counter++; //count for the processed samples d_sample_counter++; //count for the processed samples
const double **in = (const double **) &input_items[0]; //Get the input samples pointer const double **in = (const double **) &input_items[0]; //Get the input samples pointer
// ########### Output the tracking data to navigation and PVT ########## // ########### Output the tracking data to navigation and PVT ##########
// Output channel 0: Prompt correlator output Q // Output channel 0: Prompt correlator output Q
// *out[0]=(double)d_Prompt.real(); // *out[0]=(double)d_Prompt.real();
// // Output channel 1: Prompt correlator output I // // Output channel 1: Prompt correlator output I
// *out[1]=(double)d_Prompt.imag(); // *out[1]=(double)d_Prompt.imag();
// // Output channel 2: PRN absolute delay [s] // // Output channel 2: PRN absolute delay [s]
// *out[2]=d_sample_counter_seconds; // *out[2]=d_sample_counter_seconds;
// // Output channel 3: d_acc_carrier_phase_rad [rad] // // Output channel 3: d_acc_carrier_phase_rad [rad]
// *out[3]=(double)d_acc_carrier_phase_rad; // *out[3]=(double)d_acc_carrier_phase_rad;
// // Output channel 4: PRN code phase [s] // // Output channel 4: PRN code phase [s]
// *out[4]=(double)d_code_phase_samples*(1/(float)d_fs_in); // *out[4]=(double)d_code_phase_samples*(1/(float)d_fs_in);
/*! /*!
* \todo Check the HOW GPS time computation, taking into account that the preamble correlation last 160 symbols, which is 160 ms in GPS CA L1 * \todo Check the HOW GPS time computation, taking into account that the preamble correlation last 160 symbols, which is 160 ms in GPS CA L1
*/ */
// FIFO history to get the exact timestamp of the first symbol of the preamble // FIFO history to get the exact timestamp of the first symbol of the preamble
// if (d_prn_start_sample_history.size()<160) // if (d_prn_start_sample_history.size()<160)
// { // {
// // fill the queue // // fill the queue
// d_prn_start_sample_history.push_front(in[2][0]); // d_prn_start_sample_history.push_front(in[2][0]);
// consume_each(1); //one by one // consume_each(1); //one by one
// return 1; // return 1;
// }else{ // }else{
// d_prn_start_sample_history.pop_back(); // d_prn_start_sample_history.pop_back();
// d_prn_start_sample_history.push_front(in[2][0]); // d_prn_start_sample_history.push_front(in[2][0]);
// } // }
// TODO Optimize me! // TODO Optimize me!
//******* preamble correlation ******** //******* preamble correlation ********
for (unsigned int i=0;i<d_samples_per_bit*8;i++){ for (unsigned int i=0;i<d_samples_per_bit*8;i++)
if (in[1][i] < 0) // symbols clipping
{
corr_value-=d_preambles_symbols[i];
}else{
corr_value+=d_preambles_symbols[i];
}
}
d_flag_preamble=false;
//******* frame sync ******************
if (abs(corr_value)>=160){
//TODO: Rewrite with state machine
if (d_stat==0)
{
d_GPS_FSM.Event_gps_word_preamble();
d_preamble_index=d_sample_counter;//record the preamble sample stamp
std::cout<<"Preamble detection for SAT "<<d_satellite<<std::endl;
d_symbol_accumulator=0; //sync the symbol to bits integrator
d_symbol_accumulator_counter=0;
d_frame_bit_index=8;
d_stat=1; // enter into frame pre-detection status
}else if (d_stat==1) //check 6 seconds of preample separation
{
preamble_diff=abs(d_sample_counter-d_preamble_index);
if (abs(preamble_diff-6000)<1)
{
d_GPS_FSM.Event_gps_word_preamble();
d_flag_preamble=true;
d_preamble_index=d_sample_counter;//record the preamble sample stamp (t_P)
d_preamble_time_seconds=in[2][0]-d_preamble_duration_seconds; //record the PRN start sample index associated to the preamble
d_preamble_code_phase_seconds=in[4][0];
if (!d_flag_frame_sync){
d_flag_frame_sync=true;
std::cout<<" Frame sync SAT "<<d_satellite<<" with preamble start at "<<d_preamble_time_seconds<<" [s]"<<std::endl;
}
}
}
}else{
if (d_stat==1)
{
preamble_diff=d_sample_counter-d_preamble_index;
if (preamble_diff>6001){
std::cout<<"Lost of frame sync SAT "<<this->d_satellite<<" preamble_diff= "<<preamble_diff<<std::endl;
d_stat=0; //lost of frame sync
d_flag_frame_sync=false;
}
}
}
//******* code error accumulator *****
//d_preamble_phase-=in[3][0];
//******* SYMBOL TO BIT *******
d_symbol_accumulator+=in[1][d_samples_per_bit*8-1]; // accumulate the input value in d_symbol_accumulator
d_symbol_accumulator_counter++;
if (d_symbol_accumulator_counter==20)
{
if (d_symbol_accumulator>0){ //symbol to bit
d_GPS_frame_4bytes+=1; //insert the telemetry bit in LSB
}
d_symbol_accumulator=0;
d_symbol_accumulator_counter=0;
//******* bits to words ******
d_frame_bit_index++;
if (d_frame_bit_index==30)
{
d_frame_bit_index=0;
//parity check
//Each word in wordbuff is composed of:
// Bits 0 to 29 = the GPS data word
// Bits 30 to 31 = 2 LSBs of the GPS word ahead.
// prepare the extended frame [-2 -1 0 ... 30]
if (d_prev_GPS_frame_4bytes & 0x00000001)
{ {
d_GPS_frame_4bytes=d_GPS_frame_4bytes|0x40000000; if (in[1][i] < 0) // symbols clipping
{
corr_value-=d_preambles_symbols[i];
}
else
{
corr_value+=d_preambles_symbols[i];
}
} }
if (d_prev_GPS_frame_4bytes & 0x00000002) d_flag_preamble=false;
//******* frame sync ******************
if (abs(corr_value)>=160)
{ {
d_GPS_frame_4bytes=d_GPS_frame_4bytes|0x80000000; //TODO: Rewrite with state machine
if (d_stat==0)
{
d_GPS_FSM.Event_gps_word_preamble();
d_preamble_index=d_sample_counter;//record the preamble sample stamp
std::cout<<"Preamble detection for SAT "<<d_satellite<<std::endl;
d_symbol_accumulator=0; //sync the symbol to bits integrator
d_symbol_accumulator_counter=0;
d_frame_bit_index=8;
d_stat=1; // enter into frame pre-detection status
}
else if (d_stat==1) //check 6 seconds of preample separation
{
preamble_diff=abs(d_sample_counter-d_preamble_index);
if (abs(preamble_diff-6000)<1)
{
d_GPS_FSM.Event_gps_word_preamble();
d_flag_preamble=true;
d_preamble_index=d_sample_counter;//record the preamble sample stamp (t_P)
d_preamble_time_seconds=in[2][0]-d_preamble_duration_seconds; //record the PRN start sample index associated to the preamble
d_preamble_code_phase_seconds=in[4][0];
if (!d_flag_frame_sync)
{
d_flag_frame_sync=true;
std::cout<<" Frame sync SAT "<<d_satellite<<" with preamble start at "<<d_preamble_time_seconds<<" [s]"<<std::endl;
}
}
}
} }
/* Check that the 2 most recently logged words pass parity. Have to first else
invert the data bits according to bit 30 of the previous word. */
if(d_GPS_frame_4bytes & 0x40000000)
{ {
d_GPS_frame_4bytes ^= 0x3FFFFFC0; // invert the data bits (using XOR) if (d_stat==1)
{
preamble_diff=d_sample_counter-d_preamble_index;
if (preamble_diff>6001)
{
std::cout<<"Lost of frame sync SAT "<<this->d_satellite<<" preamble_diff= "<<preamble_diff<<std::endl;
d_stat=0; //lost of frame sync
d_flag_frame_sync=false;
}
}
} }
if (gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(d_GPS_frame_4bytes)) {
memcpy(&d_GPS_FSM.d_GPS_frame_4bytes,&d_GPS_frame_4bytes,sizeof(char)*4);
d_GPS_FSM.d_preamble_time_ms=d_preamble_time_seconds*1000.0;
d_GPS_FSM.Event_gps_word_valid();
d_flag_parity=true;
}else{
d_GPS_FSM.Event_gps_word_invalid();
d_flag_parity=false;
}
d_prev_GPS_frame_4bytes=d_GPS_frame_4bytes; // save the actual frame
d_GPS_frame_4bytes=d_GPS_frame_4bytes & 0;
}else{
d_GPS_frame_4bytes<<=1; //shift 1 bit left the telemetry word
}
}
// output the frame //******* code error accumulator *****
consume_each(1); //one by one //d_preamble_phase-=in[3][0];
//******* SYMBOL TO BIT *******
gps_synchro.valid_word=(d_flag_frame_sync==true and d_flag_parity==true); d_symbol_accumulator+=in[1][d_samples_per_bit*8-1]; // accumulate the input value in d_symbol_accumulator
gps_synchro.flag_preamble=d_flag_preamble; d_symbol_accumulator_counter++;
gps_synchro.preamble_delay_ms=d_preamble_time_seconds*1000.0; if (d_symbol_accumulator_counter==20)
gps_synchro.prn_delay_ms=(in[2][0]-d_preamble_duration_seconds)*1000.0; {
gps_synchro.preamble_code_phase_ms=d_preamble_code_phase_seconds*1000.0; if (d_symbol_accumulator>0)
gps_synchro.preamble_code_phase_correction_ms=(in[4][0]-d_preamble_code_phase_seconds)*1000.0; { //symbol to bit
gps_synchro.satellite_PRN=d_satellite; d_GPS_frame_4bytes+=1; //insert the telemetry bit in LSB
gps_synchro.channel_ID=d_channel; }
*out[0]=gps_synchro; d_symbol_accumulator=0;
return 1; d_symbol_accumulator_counter=0;
//******* bits to words ******
d_frame_bit_index++;
if (d_frame_bit_index==30)
{
d_frame_bit_index=0;
//parity check
//Each word in wordbuff is composed of:
// Bits 0 to 29 = the GPS data word
// Bits 30 to 31 = 2 LSBs of the GPS word ahead.
// prepare the extended frame [-2 -1 0 ... 30]
if (d_prev_GPS_frame_4bytes & 0x00000001)
{
d_GPS_frame_4bytes=d_GPS_frame_4bytes|0x40000000;
}
if (d_prev_GPS_frame_4bytes & 0x00000002)
{
d_GPS_frame_4bytes=d_GPS_frame_4bytes|0x80000000;
}
/* Check that the 2 most recently logged words pass parity. Have to first
invert the data bits according to bit 30 of the previous word. */
if(d_GPS_frame_4bytes & 0x40000000)
{
d_GPS_frame_4bytes ^= 0x3FFFFFC0; // invert the data bits (using XOR)
}
if (gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(d_GPS_frame_4bytes))
{
memcpy(&d_GPS_FSM.d_GPS_frame_4bytes,&d_GPS_frame_4bytes,sizeof(char)*4);
d_GPS_FSM.d_preamble_time_ms=d_preamble_time_seconds*1000.0;
d_GPS_FSM.Event_gps_word_valid();
d_flag_parity=true;
}
else
{
d_GPS_FSM.Event_gps_word_invalid();
d_flag_parity=false;
}
d_prev_GPS_frame_4bytes=d_GPS_frame_4bytes; // save the actual frame
d_GPS_frame_4bytes=d_GPS_frame_4bytes & 0;
}
else
{
d_GPS_frame_4bytes<<=1; //shift 1 bit left the telemetry word
}
}
// output the frame
consume_each(1); //one by one
gps_synchro.valid_word=(d_flag_frame_sync==true and d_flag_parity==true);
gps_synchro.flag_preamble=d_flag_preamble;
gps_synchro.preamble_delay_ms=d_preamble_time_seconds*1000.0;
gps_synchro.prn_delay_ms=(in[2][0]-d_preamble_duration_seconds)*1000.0;
gps_synchro.preamble_code_phase_ms=d_preamble_code_phase_seconds*1000.0;
gps_synchro.preamble_code_phase_correction_ms=(in[4][0]-d_preamble_code_phase_seconds)*1000.0;
gps_synchro.satellite_PRN=d_satellite;
gps_synchro.channel_ID=d_channel;
*out[0]=gps_synchro;
return 1;
} }
void gps_l1_ca_telemetry_decoder_cc::set_satellite(int satellite) { void gps_l1_ca_telemetry_decoder_cc::set_satellite(int satellite)
d_satellite = satellite; {
d_GPS_FSM.d_satellite_PRN=satellite; d_satellite = satellite;
LOG_AT_LEVEL(INFO) << "Navigation Satellite set to " << d_satellite; d_GPS_FSM.i_satellite_PRN=satellite;
LOG_AT_LEVEL(INFO) << "Navigation Satellite set to " << d_satellite;
} }
void gps_l1_ca_telemetry_decoder_cc::set_channel(int channel) { void gps_l1_ca_telemetry_decoder_cc::set_channel(int channel)
d_channel = channel; {
d_GPS_FSM.d_channel_ID=channel; d_channel = channel;
LOG_AT_LEVEL(INFO) << "Navigation channel set to " << channel; d_GPS_FSM.i_channel_ID=channel;
LOG_AT_LEVEL(INFO) << "Navigation channel set to " << channel;
} }

View File

@ -225,12 +225,12 @@ void GpsL1CaSubframeFsm::gps_subframe_to_nav_msg()
int subframe_ID; int subframe_ID;
// NEW GPS SUBFRAME HAS ARRIVED! // NEW GPS SUBFRAME HAS ARRIVED!
subframe_ID=d_nav.subframe_decoder(this->d_subframe); //decode the subframe subframe_ID=d_nav.subframe_decoder(this->d_subframe); //decode the subframe
std::cout<<"NAVIGATION FSM: received subframe "<<subframe_ID<<" for satellite "<<d_nav.d_satellite_PRN<<std::endl; std::cout<<"NAVIGATION FSM: received subframe "<<subframe_ID<<" for satellite "<<d_nav.i_satellite_PRN<<std::endl;
d_nav.d_satellite_PRN=d_satellite_PRN; d_nav.i_satellite_PRN=i_satellite_PRN;
d_nav.d_channel_ID=d_channel_ID; d_nav.i_channel_ID=i_channel_ID;
if (subframe_ID==1) { if (subframe_ID==1) {
d_nav.d_subframe1_timestamp_ms=this->d_preamble_time_ms; d_nav.d_subframe1_timestamp_ms=this->d_preamble_time_ms;
//std::cout<<"NAVIGATION FSM: set subframe 1 preamble timestamp for satellite "<<d_nav.d_satellite_PRN<<std::endl; //std::cout<<"NAVIGATION FSM: set subframe 1 preamble timestamp for satellite "<<d_nav.i_satellite_PRN<<std::endl;
} }
/*! /*!
* \todo change satellite validation to subframe 5 because it will have a complete set of ephemeris parameters * \todo change satellite validation to subframe 5 because it will have a complete set of ephemeris parameters

View File

@ -69,8 +69,8 @@ private:
public: public:
// channel and satellite info // channel and satellite info
int d_channel_ID; int i_channel_ID;
int d_satellite_PRN; int i_satellite_PRN;
// ephemeris queue // ephemeris queue
concurrent_queue<gps_navigation_message> *d_nav_queue; concurrent_queue<gps_navigation_message> *d_nav_queue;

View File

@ -87,8 +87,8 @@ void gps_navigation_message::reset()
d_satpos_Z=0; d_satpos_Z=0;
// info // info
d_channel_ID=0; i_channel_ID=0;
d_satellite_PRN=0; i_satellite_PRN=0;
// time synchro // time synchro
d_subframe1_timestamp_ms=0; d_subframe1_timestamp_ms=0;
@ -129,6 +129,45 @@ void gps_navigation_message::reset()
d_satvel_X=0; d_satvel_X=0;
d_satvel_Y=0; d_satvel_Y=0;
d_satvel_Z=0; d_satvel_Z=0;
//Plane A (info from http://www.navcen.uscg.gov/?Do=constellationStatus)
satelliteBlock[9] = "IIA";
satelliteBlock[31] = "IIR-M";
satelliteBlock[8] = "IIA";
satelliteBlock[7] = "IIR-M";
satelliteBlock[27] = "IIA";
//Plane B
satelliteBlock[16] = "IIR";
satelliteBlock[25] = "IIF";
satelliteBlock[28] = "IIR";
satelliteBlock[12] = "IIR-M";
satelliteBlock[30] = "IIA";
//Plane C
satelliteBlock[29] = "IIR-M";
satelliteBlock[3] = "IIA";
satelliteBlock[19] = "IIR";
satelliteBlock[17] = "IIR-M";
satelliteBlock[6] = "IIA";
//Plane D
satelliteBlock[2] = "IIR";
satelliteBlock[1] = "IIF";
satelliteBlock[21] = "IIR";
satelliteBlock[4] = "IIA";
satelliteBlock[11] = "IIR";
satelliteBlock[24] = "IIA"; // Decommissioned from active service on 04 Nov 2011
//Plane E
satelliteBlock[20] = "IIR";
satelliteBlock[22] = "IIR";
satelliteBlock[5] = "IIR-M";
satelliteBlock[18] = "IIR";
satelliteBlock[32] = "IIA";
satelliteBlock[10] = "IIA";
//Plane F
satelliteBlock[14] = "IIR";
satelliteBlock[15] = "IIR-M";
satelliteBlock[13] = "IIR";
satelliteBlock[23] = "IIR";
satelliteBlock[26] = "IIA";
} }
@ -340,7 +379,7 @@ void gps_navigation_message::satellitePosition(double transmitTime)
// debug // debug
/* /*
if (this->d_channel_ID==0){ if (this->i_channel_ID==0){
std::cout<<"tk"<<tk<<std::endl; std::cout<<"tk"<<tk<<std::endl;
std::cout<<"E="<<E<<std::endl; std::cout<<"E="<<E<<std::endl;
std::cout<<"d_dtr="<<d_dtr<<std::endl; std::cout<<"d_dtr="<<d_dtr<<std::endl;
@ -362,9 +401,7 @@ void gps_navigation_message::satellitePosition(double transmitTime)
/* Satellite's velocity. Can be useful for Vector Tracking loops */ /* Satellite's velocity. Can be useful for Vector Tracking loops */
double Omega_dot = d_OMEGA_DOT - OMEGA_EARTH_DOT; double Omega_dot = d_OMEGA_DOT - OMEGA_EARTH_DOT;
d_satvel_X = - Omega_dot * (cos(u) * r + sin(u) * r * cos(i)) + d_satpos_X * cos(Omega) - d_satpos_Y * cos(i) * sin(Omega); d_satvel_X = - Omega_dot * (cos(u) * r + sin(u) * r * cos(i)) + d_satpos_X * cos(Omega) - d_satpos_Y * cos(i) * sin(Omega);
d_satvel_Y = Omega_dot * (cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega)) + d_satpos_X * sin(Omega) + d_satpos_Y * cos(i) * cos(Omega); d_satvel_Y = Omega_dot * (cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega)) + d_satpos_X * sin(Omega) + d_satpos_Y * cos(i) * cos(Omega);
d_satvel_Z = d_satpos_Y * sin(i); d_satvel_Z = d_satpos_Y * sin(i);

View File

@ -120,6 +120,8 @@ public:
int i_WN_A; //!< Modulo 256 of the GPS week number to which the almanac reference time (d_Toa) is referenced int i_WN_A; //!< Modulo 256 of the GPS week number to which the almanac reference time (d_Toa) is referenced
std::map<int,int> almanacHealth; //!< Map that stores the health information stored in the almanac std::map<int,int> almanacHealth; //!< Map that stores the health information stored in the almanac
std::map<int,std::string> satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus
// Flags // Flags
/*! \brief If true, enhanced level of integrity assurance. /*! \brief If true, enhanced level of integrity assurance.
@ -150,8 +152,8 @@ public:
// satellite identification info // satellite identification info
int d_channel_ID; int i_channel_ID;
int d_satellite_PRN; int i_satellite_PRN;
// time synchro // time synchro
double d_subframe1_timestamp_ms; //[ms] double d_subframe1_timestamp_ms; //[ms]

View File

@ -20,7 +20,7 @@ exe gnss-sdr : main.cc
../algorithms/libs//gps_sdr_x86 ../algorithms/libs//gps_sdr_x86
../algorithms/observables/adapters//gps_l1_ca_observables ../algorithms/observables/adapters//gps_l1_ca_observables
../algorithms/observables/gnuradio_blocks//gps_l1_ca_observables_cc ../algorithms/observables/gnuradio_blocks//gps_l1_ca_observables_cc
../algorithms/PVT/libs//rinex_2_1_printer ../algorithms/PVT/libs//rinex_printer
../algorithms/PVT/libs//kml_printer ../algorithms/PVT/libs//kml_printer
../algorithms/PVT/libs//gps_l1_ca_ls_pvt ../algorithms/PVT/libs//gps_l1_ca_ls_pvt
../algorithms/output_filter/adapters//file_output_filter ../algorithms/output_filter/adapters//file_output_filter