1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-10-30 23:03:05 +00:00

- Major changes:

- The executable file and the default configuration file is now changed from "./install/mercurio" and "./conf/mercurio.conf" to "./install/gnss-sdr" and "./conf/gnss-sdr.conf", respectively.
        - Configuration file structure changed to define in a single entry the internal sampling frequency (after the signal conditioner). NOTICE that this change affects the all the adapters (acquisition, tracking, telemetry_decoder, observables, and PVT). All the adapters are now modified to work with this feature.
        - Moved several in-line GPS L1 CA parameters (a.k.a magic numbers..) to ./src/core/system_parameters/GPS_L1_CA.h definition file.
        - Tracking blocks now uses DOUBLE values in their outputs.
        - Observables and PVT now are separated. PVT and their associated libraries are moved to ./src/algorithms/PVT
        - Temporarily disabled the RINEX output (I am working on that!)
        - GNSS-SDR screen output now gives extended debug information of the receiver status and events. In the future, this output will be redirected to a log file.

- Bug fixes:
        - FILE_SIGNAL_SOURCE now works correctly when the user configures GNSS-SDR to process the entire file.
        - GPS_L1_CA_DLL_PLL now computes correctly the PRN start values.
        - GPS_L1_CA_DLL_FLL_PLL now computes correctly the PRN start values.
        - Several modifications in GPS_L1_CA_Telemetry_Decoder, GPS_L1_CA_Observables, and GPS_L1_CA_PVT modules to fix the GPS position computation.

- New features
        - Tracking blocks perform a signal integrity check against NaN outliers before the correlation process.
        - Tracking and PVT binary dump options are now documented and we provide MATLAB libraries and sample files to read it. Available in ./utils/matlab" and "./utils/matlab/libs"
        - Observables output rate can be configured. This option enables the GPS L1 CA PVT computation at a maximum rate of 1ms.
        - GPS_L1_CA_PVT now can perform a moving average Latitude, Longitude, and Altitude output for each of the Observables output. It is configurable using the configuration file.
        - Added Google Earth compatible Keyhole Markup Language (KML) output writer class (./src/algorithms/PVT/libs/kml_printer.h and ./src/algorithms/PVT/libs/kml_printer.cc ). You can see the receiver position directly using Google Earth.
        - We provide a master configuration file which includes an in-line documentation with all the new (and old) options. It can be found in ./conf/master.conf

git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@84 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
Javier Arribas
2011-12-07 17:59:34 +00:00
parent 57f7a128a5
commit 69b8ac00dc
102 changed files with 4756 additions and 914 deletions

View File

@@ -0,0 +1,103 @@
/*!
* \file gps_l1_ca_pvt.cc
* \brief Simple Least Squares implementation for GPS L1 C/A Position Velocity and Time
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "gps_l1_ca_pvt.h"
#include "configuration_interface.h"
#include "gps_l1_ca_pvt_cc.h"
#include <gnuradio/gr_io_signature.h>
#include <glog/log_severity.h>
#include <glog/logging.h>
extern concurrent_queue<gps_navigation_message> global_gps_nav_msg_queue;
using google::LogMessage;
GpsL1CaPvt::GpsL1CaPvt(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams,
gr_msg_queue_sptr queue) :
role_(role),
in_streams_(in_streams),
out_streams_(out_streams),
queue_(queue)
{
std::string default_dump_filename = "./pvt.dat";
DLOG(INFO) << "role " << role;
int averaging_depth;
averaging_depth=configuration->property(role + ".averaging_depth", 10);
bool flag_averaging;
flag_averaging=configuration->property(role + ".flag_averaging", false);
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
pvt_ = gps_l1_ca_make_pvt_cc(in_streams_, queue_, dump_, dump_filename_, averaging_depth, flag_averaging);
DLOG(INFO) << "pvt(" << pvt_->unique_id() << ")";
// set the navigation msg queue;
pvt_->set_navigation_queue(&global_gps_nav_msg_queue);
DLOG(INFO) << "global navigation message queue assigned to pvt ("<< pvt_->unique_id() << ")";
}
GpsL1CaPvt::~GpsL1CaPvt()
{}
void GpsL1CaPvt::connect(gr_top_block_sptr top_block)
{
// Nothing to connect internally
DLOG(INFO) << "nothing to connect internally";
}
void GpsL1CaPvt::disconnect(gr_top_block_sptr top_block)
{
// Nothing to disconnect
}
gr_basic_block_sptr GpsL1CaPvt::get_left_block()
{
return pvt_;
}
gr_basic_block_sptr GpsL1CaPvt::get_right_block()
{
return pvt_;
}

View File

@@ -0,0 +1,94 @@
/*!
* \file gps_l1_ca_pvt.h
* \brief Simple Least Squares implementation for GPS L1 C/A Position Velocity and Time
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GPS_L1_CA_PVT_H_
#define GPS_L1_CA_PVT_H_
#include "pvt_interface.h"
#include "gps_l1_ca_pvt_cc.h"
#include <gnuradio/gr_msg_queue.h>
class ConfigurationInterface;
class GpsL1CaPvt : public PvtInterface
{
public:
GpsL1CaPvt(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams,
gr_msg_queue_sptr queue);
virtual ~GpsL1CaPvt();
std::string role()
{
return role_;
}
std::string implementation()
{
return "pvt";
}
void connect(gr_top_block_sptr top_block);
void disconnect(gr_top_block_sptr top_block);
gr_basic_block_sptr get_left_block();
gr_basic_block_sptr get_right_block();
void reset()
{
return;
};
// all blocks must have an intem_size() function implementation
size_t item_size()
{
return sizeof(gr_complex);
}
private:
gps_l1_ca_pvt_cc_sptr pvt_;
bool dump_;
unsigned int fs_in_;
std::string dump_filename_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
gr_msg_queue_sptr queue_;
};
#endif

View File

@@ -0,0 +1,3 @@
project : build-dir ../../../../build ;
obj gps_l1_ca_pvt : gps_l1_ca_pvt.cc ;

View File

@@ -0,0 +1,167 @@
/*!
* \file gps_l1_ca_pvt_cc.cc
* \brief Position Velocity and Time computation for GPS L1 C/A using Least Squares algorithm
* \author Javier Arribas, 2011. jarribas(at)cttc.es
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include <iostream>
#include <sstream>
#include <vector>
#include <map>
#include <algorithm>
#include <bitset>
#include <cmath>
#include "math.h"
#include "gps_l1_ca_pvt_cc.h"
#include "control_message_factory.h"
#include <gnuradio/gr_io_signature.h>
#include <glog/log_severity.h>
#include <glog/logging.h>
using google::LogMessage;
using namespace std;
gps_l1_ca_pvt_cc_sptr
gps_l1_ca_make_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging) {
return gps_l1_ca_pvt_cc_sptr(new gps_l1_ca_pvt_cc(nchannels, queue, dump, dump_filename, averaging_depth, flag_averaging));
}
gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging) :
gr_block ("gps_l1_ca_pvt_cc", gr_make_io_signature (nchannels, nchannels, sizeof(gnss_pseudorange)),
gr_make_io_signature(1, 1, sizeof(gr_complex))) {
// initialize internal vars
d_queue = queue;
d_dump = dump;
d_nchannels = nchannels;
d_dump_filename=dump_filename;
std::string kml_dump_filename;
kml_dump_filename=d_dump_filename;
kml_dump_filename.append(".kml");
d_kml_dump.set_headers(kml_dump_filename);
d_dump_filename.append(".dat");
d_averaging_depth=averaging_depth;
d_flag_averaging=flag_averaging;
/*!
* \todo Enable RINEX printer: The actual RINEX printer need a complete refactoring and some bug fixing work
*/
//d_rinex_printer.set_headers("GNSS-SDR");
d_ls_pvt=new gps_l1_ca_ls_pvt(nchannels,d_dump_filename,d_dump);
d_ls_pvt->set_averaging_depth(d_averaging_depth);
d_ephemeris_clock_s=0.0;
d_sample_counter=0;
}
gps_l1_ca_pvt_cc::~gps_l1_ca_pvt_cc() {
d_kml_dump.close_file();
delete d_ls_pvt;
}
bool pseudoranges_pairCompare_min( pair<int,gnss_pseudorange> a, pair<int,gnss_pseudorange> b)
{
return (a.second.pseudorange_m) < (b.second.pseudorange_m);
}
int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) {
d_sample_counter++;
map<int,gnss_pseudorange> gnss_pseudoranges_map;
map<int,gnss_pseudorange>::iterator gnss_pseudoranges_iter;
gnss_pseudorange **in = (gnss_pseudorange **) &input_items[0]; //Get the input pointer
for (unsigned int i=0;i<d_nchannels;i++)
{
if (in[i][0].valid==true)
{
gnss_pseudoranges_map.insert(pair<int,gnss_pseudorange>(in[i][0].SV_ID,in[i][0])); //record the valid psudorrange in a map
}
}
//debug print
cout << setprecision(16);
for(gnss_pseudoranges_iter = gnss_pseudoranges_map.begin();
gnss_pseudoranges_iter != gnss_pseudoranges_map.end();
gnss_pseudoranges_iter++)
{
cout<<"Pseudoranges(SV ID,pseudorange [m]) =("<<gnss_pseudoranges_iter->first<<","<<gnss_pseudoranges_iter->second.pseudorange_m<<")"<<endl;
}
// ############ 1. READ EPHEMERIS FROM QUEUE ######################
// find the minimum index (nearest satellite, will be the reference)
gnss_pseudoranges_iter=min_element(gnss_pseudoranges_map.begin(),gnss_pseudoranges_map.end(),pseudoranges_pairCompare_min);
gps_navigation_message nav_msg;
while (d_nav_queue->try_pop(nav_msg)==true)
{
cout<<"New ephemeris record has arrived from SAT ID "<<nav_msg.d_satellite_PRN<<endl;
d_last_nav_msg=nav_msg;
d_ls_pvt->d_ephemeris[nav_msg.d_channel_ID]=nav_msg;
// **** update pseudoranges clock ****
if (nav_msg.d_satellite_PRN==gnss_pseudoranges_iter->second.SV_ID)
{
d_ephemeris_clock_s=d_last_nav_msg.d_TOW;
d_ephemeris_timestamp_ms=d_last_nav_msg.d_subframe1_timestamp_ms;
}
// **** write ephemeris to RINES NAV file
//d_rinex_printer.LogRinex2Nav(nav_msg);
}
// ############ 2. COMPUTE THE PVT ################################
// write the pseudoranges to RINEX OBS file
// 1- need a valid clock
if (d_ephemeris_clock_s>0 and d_last_nav_msg.d_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);
// compute on the fly PVT solution
//std::cout<<"diff_clock_ephemerids="<<(gnss_pseudoranges_iter->second.timestamp_ms-d_ephemeris_timestamp_ms)/1000.0<<"\r\n";
if (d_ls_pvt->get_PVT(gnss_pseudoranges_map,
d_ephemeris_clock_s+(gnss_pseudoranges_iter->second.timestamp_ms-d_ephemeris_timestamp_ms)/1000.0,
d_flag_averaging)==true)
{
d_kml_dump.print_position(d_ls_pvt,d_flag_averaging);
}
}
consume_each(1); //one by one
return 0;
}

View File

@@ -0,0 +1,101 @@
/*!
* \file gps_l1_ca_pvt_cc.h
* \brief Position Velocity and Time computation for GPS L1 C/A using Least Squares algorithm
* \author Javier Arribas, 2011. jarribas(at)cttc.es
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GPS_L1_CA_PVT_CC_H
#define GPS_L1_CA_PVT_CC_H
#include <fstream>
#include <gnuradio/gr_block.h>
#include <gnuradio/gr_msg_queue.h>
#include <queue>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include "concurrent_queue.h"
#include "gps_navigation_message.h"
#include "kml_printer.h"
#include "rinex_2_1_printer.h"
#include "gps_l1_ca_ls_pvt.h"
#include "GPS_L1_CA.h"
class gps_l1_ca_pvt_cc;
typedef boost::shared_ptr<gps_l1_ca_pvt_cc> gps_l1_ca_pvt_cc_sptr;
gps_l1_ca_pvt_cc_sptr
gps_l1_ca_make_pvt_cc(unsigned int n_channels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging);
class gps_l1_ca_pvt_cc : public gr_block {
private:
friend gps_l1_ca_pvt_cc_sptr
gps_l1_ca_make_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging);
gps_l1_ca_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging);
// class private vars
gr_msg_queue_sptr d_queue;
bool d_dump;
unsigned int d_nchannels;
std::string d_dump_filename;
std::ofstream d_dump_file;
int d_averaging_depth;
bool d_flag_averaging;
long unsigned int d_sample_counter;
kml_printer d_kml_dump;
concurrent_queue<gps_navigation_message> *d_nav_queue; // Navigation ephemeris queue
gps_navigation_message d_last_nav_msg; //last navigation message
double d_ephemeris_clock_s;
double d_ephemeris_timestamp_ms;
gps_l1_ca_ls_pvt *d_ls_pvt;
//rinex_printer d_rinex_printer; // RINEX printer class
public:
~gps_l1_ca_pvt_cc ();
void set_navigation_queue(concurrent_queue<gps_navigation_message> *nav_queue){d_nav_queue=nav_queue;}
int general_work (int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
};
#endif

View File

@@ -0,0 +1,3 @@
project : build-dir ../../../../build ;
obj gps_l1_ca_pvt_cc : gps_l1_ca_pvt_cc.cc ;

View File

@@ -0,0 +1,3 @@
build-project adapters ;
build-project gnuradio_blocks ;
build-project libs ;

View File

@@ -46,16 +46,43 @@
#include "gps_l1_ca_ls_pvt.h"
gps_l1_ca_ls_pvt::gps_l1_ca_ls_pvt(int nchannels)
gps_l1_ca_ls_pvt::gps_l1_ca_ls_pvt(int nchannels,std::string dump_filename, bool flag_dump_to_file)
{
// init empty ephemerids for all the available GNSS channels
d_nchannels=nchannels;
d_ephemeris=new gps_navigation_message[nchannels];
d_dump_filename=dump_filename;
d_flag_dump_enabled=flag_dump_to_file;
d_averaging_depth=0;
// ############# ENABLE DATA FILE LOG #################
if (d_flag_dump_enabled==true)
{
if (d_dump_file.is_open()==false)
{
try {
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
std::cout<<"PVT lib dump enabled Log file: "<<d_dump_filename.c_str()<<std::endl;
}
catch (std::ifstream::failure e) {
std::cout << "Exception opening PVT lib dump file "<<e.what()<<"\r\n";
}
}
}
}
void gps_l1_ca_ls_pvt::set_averaging_depth(int depth)
{
d_averaging_depth=depth;
}
gps_l1_ca_ls_pvt::~gps_l1_ca_ls_pvt()
{
delete d_ephemeris;
d_dump_file.close();
delete[] d_ephemeris;
}
arma::vec gps_l1_ca_ls_pvt::e_r_corr(double traveltime, arma::vec X_sat) {
@@ -205,9 +232,9 @@ arma::vec gps_l1_ca_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arma
return pos;
}
void gps_l1_ca_ls_pvt::get_PVT(std::map<int,float> pseudoranges,double GPS_current_time)
bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,gnss_pseudorange> gnss_pseudoranges_map,double GPS_current_time,bool flag_averaging)
{
std::map<int,float>::iterator pseudoranges_iter;
std::map<int,gnss_pseudorange>::iterator gnss_pseudoranges_iter;
//ITPP
//mat W=eye(d_nchannels); //channels weights matrix
//vec obs=zeros(d_nchannels); // pseudoranges observation vector
@@ -223,10 +250,13 @@ void gps_l1_ca_ls_pvt::get_PVT(std::map<int,float> pseudoranges,double GPS_curre
{
if (d_ephemeris[i].satellite_validation()==true)
{
pseudoranges_iter=pseudoranges.find(d_ephemeris[i].d_satellite_PRN);
if (pseudoranges_iter!=pseudoranges.end())
gnss_pseudoranges_iter=gnss_pseudoranges_map.find(d_ephemeris[i].d_satellite_PRN);
if (gnss_pseudoranges_iter!=gnss_pseudoranges_map.end())
{
W(i,i)=1; // TODO: Place here the satellite CN0 (power level, or weight factor)
/*!
* \todo Place here the satellite CN0 (power level, or weight factor)
*/
W(i,i)=1;
// compute the GPS master clock
d_ephemeris[i].master_clock(GPS_current_time);
// compute the satellite current ECEF position
@@ -236,7 +266,9 @@ void gps_l1_ca_ls_pvt::get_PVT(std::map<int,float> pseudoranges,double GPS_curre
satpos(0,i)=d_ephemeris[i].d_satpos_X;
satpos(1,i)=d_ephemeris[i].d_satpos_Y;
satpos(2,i)=d_ephemeris[i].d_satpos_Z;
obs(i)=pseudoranges_iter->second+d_ephemeris[i].d_satClkCorr*GPS_C_m_s;
std::cout<<"ECEF satellite SV ID="<<d_ephemeris[i].d_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";
obs(i)=gnss_pseudoranges_iter->second.pseudorange_m+d_ephemeris[i].d_satClkCorr*GPS_C_m_s;
valid_obs++;
}else{
// no valid pseudorange for the current channel
@@ -254,9 +286,101 @@ void gps_l1_ca_ls_pvt::get_PVT(std::map<int,float> pseudoranges,double GPS_curre
{
arma::vec mypos;
mypos=leastSquarePos(satpos,obs,W);
std::cout << "Position ("<<GPS_current_time<<") ECEF = " << mypos << std::endl;
std::cout << "Position at TOW="<<GPS_current_time<<" is ECEF (X,Y,Z) = " << mypos << std::endl;
cart2geo(mypos(0), mypos(1), mypos(2), 4);
std::cout << "Position ("<<GPS_current_time<<") Lat = " << d_latitude_d << " Long ="<< d_longitude_d <<" Height="<<d_height_m<< std::endl;
std::cout << "Position at TOW="<<GPS_current_time<<" is Lat = " << d_latitude_d << " [º] Long ="<< d_longitude_d <<" [º] Height="<<d_height_m<<" [m]\r\n";
// ######## LOG FILE #########
if(d_flag_dump_enabled==true) {
// MULTIPLEXED FILE RECORDING - Record results to file
try {
double tmp_double;
// PVT GPS time
tmp_double=GPS_current_time;
d_dump_file.write((char*)&tmp_double, sizeof(double));
// ECEF User Position East [m]
tmp_double=mypos(0);
d_dump_file.write((char*)&tmp_double, sizeof(double));
// ECEF User Position North [m]
tmp_double=mypos(1);
d_dump_file.write((char*)&tmp_double, sizeof(double));
// ECEF User Position Up [m]
tmp_double=mypos(2);
d_dump_file.write((char*)&tmp_double, sizeof(double));
// User clock offset [s]
tmp_double=mypos(3);
d_dump_file.write((char*)&tmp_double, sizeof(double));
// GEO user position Latitude [deg]
tmp_double=d_latitude_d;
d_dump_file.write((char*)&tmp_double, sizeof(double));
// GEO user position Longitude [deg]
tmp_double=d_longitude_d;
d_dump_file.write((char*)&tmp_double, sizeof(double));
// GEO user position Height [m]
tmp_double=d_height_m;
d_dump_file.write((char*)&tmp_double, sizeof(double));
}
catch (std::ifstream::failure e) {
std::cout << "Exception writing PVT lib dump file "<<e.what()<<"\r\n";
}
}
// MOVING AVERAGE PVT
if (flag_averaging==true)
{
if (d_hist_longitude_d.size()==(unsigned int)d_averaging_depth)
{
// Pop oldest value
d_hist_longitude_d.pop_back();
d_hist_latitude_d.pop_back();
d_hist_height_m.pop_back();
// Push new values
d_hist_longitude_d.push_front(d_longitude_d);
d_hist_latitude_d.push_front(d_latitude_d);
d_hist_height_m.push_front(d_height_m);
d_avg_latitude_d=0;
d_avg_longitude_d=0;
d_avg_height_m=0;
for (unsigned int i=0;i<d_hist_longitude_d.size();i++)
{
d_avg_latitude_d=d_avg_latitude_d+d_hist_latitude_d.at(i);
d_avg_longitude_d=d_avg_longitude_d+d_hist_longitude_d.at(i);
d_avg_height_m=d_avg_height_m+d_hist_height_m.at(i);
}
d_avg_latitude_d=d_avg_latitude_d/(double)d_averaging_depth;
d_avg_longitude_d=d_avg_longitude_d/(double)d_averaging_depth;
d_avg_height_m=d_avg_height_m/(double)d_averaging_depth;
return true; //indicates that the returned position is valid
}else{
//int current_depth=d_hist_longitude_d.size();
// Push new values
d_hist_longitude_d.push_front(d_longitude_d);
d_hist_latitude_d.push_front(d_latitude_d);
d_hist_height_m.push_front(d_height_m);
d_avg_latitude_d=d_latitude_d;
d_avg_longitude_d=d_longitude_d;
d_avg_height_m=d_height_m;
return false;//indicates that the returned position is not valid yet
// output the average, although it will not have the full historic available
// d_avg_latitude_d=0;
// d_avg_longitude_d=0;
// d_avg_height_m=0;
// for (unsigned int i=0;i<d_hist_longitude_d.size();i++)
// {
// d_avg_latitude_d=d_avg_latitude_d+d_hist_latitude_d.at(i);
// d_avg_longitude_d=d_avg_longitude_d+d_hist_longitude_d.at(i);
// d_avg_height_m=d_avg_height_m+d_hist_height_m.at(i);
// }
// d_avg_latitude_d=d_avg_latitude_d/(double)current_depth;
// d_avg_longitude_d=d_avg_longitude_d/(double)current_depth;
// d_avg_height_m=d_avg_height_m/(double)current_depth;
}
}else{
return true;//indicates that the returned position is valid
}
}else{
return false;
}
}
void gps_l1_ca_ls_pvt::cart2geo(double X, double Y, double Z, int elipsoid_selection)

View File

@@ -30,6 +30,7 @@
#ifndef GPS_L1_CA_LS_PVT_H_
#define GPS_L1_CA_LS_PVT_H_
#include <fstream>
#include <string>
#include <iostream>
#include <sstream>
@@ -67,14 +68,30 @@ public:
double d_latitude_d;
double d_longitude_d;
double d_height_m;
//averaging
std::deque<double> d_hist_latitude_d;
std::deque<double> d_hist_longitude_d;
std::deque<double> d_hist_height_m;
int d_averaging_depth;
double d_avg_latitude_d;
double d_avg_longitude_d;
double d_avg_height_m;
double d_x_m;
double d_y_m;
double d_z_m;
gps_l1_ca_ls_pvt(int nchannels);
bool d_flag_dump_enabled;
std::string d_dump_filename;
std::ofstream d_dump_file;
void set_averaging_depth(int depth);
gps_l1_ca_ls_pvt(int nchannels,std::string dump_filename, bool flag_dump_to_file);
~gps_l1_ca_ls_pvt();
void get_PVT(std::map<int,float> pseudoranges,double GPS_current_time);
bool get_PVT(std::map<int,gnss_pseudorange> pseudoranges,double GPS_current_time,bool flag_averaging);
void cart2geo(double X, double Y, double Z, int elipsoid_selection);
};

View File

@@ -1,4 +1,5 @@
project : build-dir ../../../../build ;
obj rinex_2_1_printer : rinex_2_1_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 ;

View File

@@ -0,0 +1,126 @@
/*!
* \file kml_printer.cc
* \brief Prints PVT information to a GoogleEarth kml file
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "kml_printer.h"
#include <glog/log_severity.h>
#include <glog/logging.h>
#include <time.h>
bool kml_printer::set_headers(std::string filename)
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
kml_file.open(filename.c_str());
if (kml_file.is_open())
{
DLOG(INFO)<<"KML printer writting on "<<filename.c_str();
kml_file<<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
<<"<kml xmlns=\"http://www.opengis.net/kml/2.2\">\r\n"
<<" <Document>\r\n"
<<" <name>GNSS Track</name>\r\n"
<<" <description>GNSS-SDR Receiver position log file created at "<<asctime (timeinfo)
<<" </description>\r\n"
<<"<Style id=\"yellowLineGreenPoly\">\r\n"
<<" <LineStyle>\r\n"
<<" <color>7f00ffff</color>\r\n"
<<" <width>1</width>\r\n"
<<" </LineStyle>\r\n"
<<"<PolyStyle>\r\n"
<<" <color>7f00ff00</color>\r\n"
<<"</PolyStyle>\r\n"
<<"</Style>\r\n"
<<"<Placemark>\r\n"
<<"<name>GNSS-SDR PVT</name>\r\n"
<<"<description>GNSS-SDR position log</description>\r\n"
<<"<styleUrl>#yellowLineGreenPoly</styleUrl>\r\n"
<<"<LineString>\r\n"
<<"<extrude>0</extrude>\r\n"
<<"<tessellate>1</tessellate>\r\n"
<<"<altitudeMode>absolute</altitudeMode>\r\n"
<<"<coordinates>\r\n";
return true;
}else{
return false;
}
}
bool kml_printer::print_position(gps_l1_ca_ls_pvt* position,bool print_average_values)
{
double latitude;
double longitude;
double height;
if (print_average_values==false)
{
latitude=position->d_latitude_d;
longitude=position->d_longitude_d;
height=position->d_height_m;
}else{
latitude=position->d_avg_latitude_d;
longitude=position->d_avg_longitude_d;
height=position->d_avg_height_m;
}
if (kml_file.is_open())
{
kml_file<<longitude<<","<<latitude<<","<<height<<"\r\n";
return true;
}else
{
return false;
}
}
bool kml_printer::close_file()
{
if (kml_file.is_open())
{
kml_file<<"</coordinates>\r\n"
<<"</LineString>\r\n"
<<"</Placemark>\r\n"
<<"</Document>\r\n"
<<"</kml>";
kml_file.close();
return true;
}else{
return false;
}
}
kml_printer::kml_printer ()
{
}
kml_printer::~kml_printer ()
{
}

View File

@@ -0,0 +1,59 @@
/*!
* \file kml_printer.h
* \brief Prints PVT information to a GoogleEarth kml file
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef KML_PRINTER_H_
#define KML_PRINTER_H_
#include <iostream>
#include <fstream>
#include "gps_l1_ca_ls_pvt.h"
class kml_printer
{
private:
std::ofstream kml_file;
public:
bool set_headers(std::string filename);
bool print_position(gps_l1_ca_ls_pvt* position,bool print_average_values);
bool close_file();
kml_printer();
~kml_printer();
};
#endif

View File

@@ -30,7 +30,7 @@
*/
#include "gps_l1_ca_gps_sdr_acquisition.h"
#include "GPS_L1_CA.h"
#include "configuration_interface.h"
#include <gnuradio/gr_io_signature.h>
@@ -63,7 +63,7 @@ GpsL1CaGpsSdrAcquisition::GpsL1CaGpsSdrAcquisition(
//vector_length_ = configuration->property(role + ".vector_length", 2048);
satellite_ = 0;
fs_in_ = configuration->property(role + ".fs_in", 2048000);
fs_in_ = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
if_ = configuration->property(role + ".ifreq", 0);
dump_ = configuration->property(role + ".dump", false);
doppler_max_ = 0;
@@ -74,9 +74,7 @@ GpsL1CaGpsSdrAcquisition::GpsL1CaGpsSdrAcquisition(
//vector_length_=ceil((float)fs_in_*((float)acquisition_ms_/1000));
//--- Find number of samples per spreading code ----------------------------
const int32 _codeFreqBasis = 1023000; //Hz
const int32 _codeLength = 1023;
vector_length_ = round(fs_in_ / (_codeFreqBasis / _codeLength));
vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
printf("vector_length_ %i\n\r", vector_length_);

View File

@@ -32,7 +32,7 @@
*/
#include "gps_l1_ca_pcps_acquisition.h"
#include "GPS_L1_CA.h"
#include "configuration_interface.h"
#include <iostream>
#include <gnuradio/gr_io_signature.h>
@@ -63,7 +63,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
default_item_type);
satellite_ = 0;
fs_in_ = configuration->property(role + ".fs_in", 2048000);
fs_in_ = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
if_ = configuration->property(role + ".ifreq", 0);
dump_ = configuration->property(role + ".dump", false);
shift_resolution_ = configuration->property(role + ".doppler_max", 15);
@@ -72,12 +72,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
default_dump_filename);
//--- Find number of samples per spreading code ----------------------------
const signed int _codeFreqBasis = 1023000; //Hz
const signed int _codeLength = 1023;
std::cout << fs_in_ << " " << role << std::endl;
vector_length_ = round(fs_in_ / (_codeFreqBasis / _codeLength));
printf("vector_length_ %i\n\r", vector_length_);
vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
if (item_type_.compare("gr_complex") == 0)
{

View File

@@ -31,7 +31,7 @@
*/
#include "gps_l1_ca_tong_pcps_acquisition.h"
#include "GPS_L1_CA.h"
#include "configuration_interface.h"
#include <gnuradio/gr_io_signature.h>
@@ -64,7 +64,7 @@ GpsL1CaTongPcpsAcquisition::GpsL1CaTongPcpsAcquisition(
std::cout << "item type " << item_type_ << std::endl;
satellite_ = 0;
fs_in_ = configuration->property(role + ".fs_in", 2048000);
fs_in_ = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
if_ = configuration->property(role + ".ifreq", 0);
dump_ = configuration->property(role + ".dump", false);
doppler_max_ = configuration->property(role + ".doppler_max", 10);
@@ -73,11 +73,7 @@ GpsL1CaTongPcpsAcquisition::GpsL1CaTongPcpsAcquisition(
default_dump_filename);
//--- Find number of samples per spreading code ----------------------------
const signed int _codeFreqBasis = 1023000; //Hz
const signed int _codeLength = 1023;
vector_length_ = round(fs_in_ / (_codeFreqBasis / _codeLength));
printf("vector_length_ %i\n\r", vector_length_);
vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
if (item_type_.compare("gr_complex") == 0)
{

View File

@@ -31,9 +31,6 @@
* -------------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gps_l1_ca_gps_sdr_acquisition_cc.h"
#include "control_message_factory.h"
@@ -126,15 +123,15 @@ gps_l1_ca_gps_sdr_acquisition_cc::gps_l1_ca_gps_sdr_acquisition_cc(
gps_l1_ca_gps_sdr_acquisition_cc::~gps_l1_ca_gps_sdr_acquisition_cc()
{
delete d_sine_if;
delete d_sine_250;
delete d_sine_500;
delete d_sine_750;
delete d_fft_codes;
delete d_fft_if;
delete d_fft_250;
delete d_fft_500;
delete d_fft_750;
delete[] d_sine_if;
delete[] d_sine_250;
delete[] d_sine_500;
delete[] d_sine_750;
delete[] d_fft_codes;
delete[] d_fft_if;
delete[] d_fft_250;
delete[] d_fft_500;
delete[] d_fft_750;
if (d_dump)
{

View File

@@ -30,10 +30,6 @@
*
* -------------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gps_l1_ca_gps_sdr_acquisition_ss.h"
#include "gps_sdr_simd.h"
@@ -129,12 +125,12 @@ gps_l1_ca_gps_sdr_acquisition_ss::gps_l1_ca_gps_sdr_acquisition_ss(
gps_l1_ca_gps_sdr_acquisition_ss::~gps_l1_ca_gps_sdr_acquisition_ss()
{
delete d_baseband_signal;
delete d_baseband_signal_shift;
delete d_sine_if;
delete d_sine_250;
delete d_sine_500;
delete d_sine_750;
delete[] d_baseband_signal;
delete[] d_baseband_signal_shift;
delete[] d_sine_if;
delete[] d_sine_250;
delete[] d_sine_500;
delete[] d_sine_750;
delete d_pFFT;
delete d_piFFT;

View File

@@ -31,10 +31,6 @@
* -------------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gps_l1_ca_pcps_acquisition_cc.h"
#include "gps_sdr_signal_processing.h"
#include "control_message_factory.h"
@@ -117,8 +113,10 @@ gps_l1_ca_pcps_acquisition_cc::gps_l1_ca_pcps_acquisition_cc(
gps_l1_ca_pcps_acquisition_cc::~gps_l1_ca_pcps_acquisition_cc()
{
delete d_sine_if;
delete d_fft_codes;
delete[] d_sine_if;
delete[] d_fft_codes;
delete d_ifft;
delete d_fft_if;
if (d_dump)
{

View File

@@ -29,9 +29,6 @@
*
* -------------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gps_l1_ca_tong_pcps_acquisition_cc.h"
#include "gps_sdr_signal_processing.h"
@@ -129,8 +126,11 @@ gps_l1_ca_tong_pcps_acquisition_cc::gps_l1_ca_tong_pcps_acquisition_cc(
gps_l1_ca_tong_pcps_acquisition_cc::~gps_l1_ca_tong_pcps_acquisition_cc()
{
delete d_if_sin;
delete d_ca_codes;
delete[] d_if_sin;
delete[] d_ca_codes;
delete[] d_aux_ca_code;
delete d_fft_if;
delete d_ifft;
if (d_dump)
{

View File

@@ -77,7 +77,7 @@ Channel::Channel(ConfigurationInterface *configuration, unsigned int channel,
repeat_ = configuration->property("Acquisition" + boost::lexical_cast<
std::string>(channel_) + ".repeat_satellite", false);
std::cout << "Channel " << channel_ << " satellite repeat = " << repeat_
DLOG(INFO) << "Channel " << channel_ << " satellite repeat = " << repeat_
<< std::endl;
acq_->set_channel_queue(&channel_internal_queue_);

View File

@@ -6,4 +6,5 @@ build-project signal_source ;
build-project tracking ;
build-project telemetry_decoder ;
build-project observables ;
build-project PVT ;
build-project output_filter ;

View File

@@ -333,7 +333,7 @@ int32 run_agc(CPX *_buff, int32 _samps, int32 _bits, int32 _scale)
p = (int16 *)&_buff[0];
val = (1 << _scale - 1);
val = (1 << (_scale - 1));
max = 1 << _bits;
num = 0;

View File

@@ -497,7 +497,7 @@ void sse_cmul(CPX *A, CPX *B, int32 cnt)
int32 cnt1;
int32 cnt2;
volatile int32 M[4] = {0xffff0001, 0x00010001, 0xffff0001, 0x00010001}; //{1,-1,1,1,1,-1,1,1};
//volatile int32 M[4] = {0xffff0001, 0x00010001, 0xffff0001, 0x00010001}; //{1,-1,1,1,1,-1,1,1};
cnt1 = cnt/4;
cnt2 = cnt-4*cnt1;
@@ -571,7 +571,7 @@ void sse_cmuls(CPX *A, CPX *B, int32 cnt, int32 shift)
int32 cnt2;
int32 round;
volatile int32 M[4] = {0xffff0001, 0x00010001, 0xffff0001, 0x00010001}; //{1,-1,1,1,1,-1,1,1};
//volatile int32 M[4] = {0xffff0001, 0x00010001, 0xffff0001, 0x00010001}; //{1,-1,1,1,1,-1,1,1};
cnt1 = cnt/4;
cnt2 = cnt-4*cnt1;
@@ -652,7 +652,7 @@ void sse_cmulsc(CPX *A, CPX *B, CPX *C, int32 cnt, int32 shift)
int32 cnt2;
int32 round;
volatile int32 M[4] = {0xffff0001, 0x00010001, 0xffff0001, 0x00010001}; //{1,-1,1,1,1,-1,1,1};
//volatile int32 M[4] = {0xffff0001, 0x00010001, 0xffff0001, 0x00010001}; //{1,-1,1,1,1,-1,1,1};
cnt1 = cnt/4;
cnt2 = cnt-4*cnt1;

View File

@@ -290,7 +290,7 @@ void x86_float_max(float* _A, unsigned int* _index, float* _magt, unsigned int _
mag = index = 0;
for(int i=0; i<_cnt; i++) {
for(unsigned int i=0; i<_cnt; i++) {
if(_A[i] > mag) {
index = i;
mag = _A[i];

View File

@@ -60,15 +60,21 @@ GpsL1CaObservables::GpsL1CaObservables(ConfigurationInterface* configuration,
queue_(queue)
{
int output_rate_ms;
output_rate_ms=configuration->property(role + ".output_rate_ms", 500);
std::string default_dump_filename = "./observables.dat";
DLOG(INFO) << "role " << role;
bool flag_averaging;
flag_averaging=configuration->property(role + ".flag_averaging", false);
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
fs_in_ = configuration->property(role + ".fs_in", 0);
fs_in_ = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
observables_ = gps_l1_ca_make_observables_cc(in_streams_, queue_, dump_);
observables_ = gps_l1_ca_make_observables_cc(in_streams_, queue_, dump_,dump_filename_,output_rate_ms,flag_averaging);
observables_->set_fs_in(fs_in_);
DLOG(INFO) << "pseudorange(" << observables_->unique_id() << ")";

View File

@@ -1,17 +1,32 @@
/**
* Copyright notice
/*!
* \file gps_l1_ca_observables_cc.cc
* \brief Pseudorange computation module for GPS L1 C/A
* \author Javier Arribas, 2011. jarribas(at)cttc.es
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
/**
* Author: Javier Arribas, 2011. jarribas(at)cttc.es
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <iostream>
#include <sstream>
#include <vector>
@@ -37,165 +52,236 @@ using namespace std;
gps_l1_ca_observables_cc_sptr
gps_l1_ca_make_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump) {
gps_l1_ca_make_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging) {
return gps_l1_ca_observables_cc_sptr(new gps_l1_ca_observables_cc(nchannels, queue, dump));
return gps_l1_ca_observables_cc_sptr(new gps_l1_ca_observables_cc(nchannels, queue, dump, dump_filename, output_rate_ms, flag_averaging));
}
gps_l1_ca_observables_cc::gps_l1_ca_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump) :
gps_l1_ca_observables_cc::gps_l1_ca_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging) :
gr_block ("gps_l1_ca_observables_cc", gr_make_io_signature (nchannels, nchannels, sizeof(gnss_synchro)),
gr_make_io_signature(1, 1, sizeof(gr_complex))) {
//TODO: change output channels to have Pseudorange GNURadio signature: nchannels input (float), nchannels output (float)
gr_make_io_signature(nchannels, nchannels, sizeof(gnss_pseudorange))) {
// initialize internal vars
d_queue = queue;
d_dump = dump;
d_nchannels = nchannels;
d_rinex_printer.set_headers("GNSS-SDR"); //TODO: read filename from config
d_ls_pvt=new gps_l1_ca_ls_pvt(nchannels);
d_ephemeris_clock_s=0.0;
if (d_dump==true)
{
std::stringstream d_dump_filename_str;//create a stringstream to form the dump filename
d_dump_filename_str<<"./data/obs.dat"; //TODO: get filename and path from config in the adapter
d_dump_filename=d_dump_filename_str.str();
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
}
d_output_rate_ms=output_rate_ms;
d_history_prn_delay_ms= new std::deque<double>[d_nchannels];
d_dump_filename=dump_filename;
d_flag_averaging=flag_averaging;
// ############# ENABLE DATA FILE LOG #################
if (d_dump==true)
{
if (d_dump_file.is_open()==false)
{
try {
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
std::cout<<"Observables dump enabled Log file: "<<d_dump_filename.c_str()<<std::endl;
}
catch (std::ifstream::failure e) {
std::cout << "Exception opening observables dump file "<<e.what()<<"\r\n";
}
}
}
}
gps_l1_ca_observables_cc::~gps_l1_ca_observables_cc() {
delete d_ls_pvt;
d_dump_file.close();
delete[] d_history_prn_delay_ms;
}
bool pairCompare_min( pair<int,gnss_synchro> a, pair<int,gnss_synchro> b)
bool pairCompare_gnss_synchro( pair<int,gnss_synchro> a, pair<int,gnss_synchro> b)
{
return (a.second.preamble_delay_ms+a.second.prn_delay_ms) < (b.second.preamble_delay_ms+b.second.prn_delay_ms);
return (a.second.preamble_delay_ms) < (b.second.preamble_delay_ms);
}
bool pairCompare_max( pair<int,gnss_synchro> a, pair<int,gnss_synchro> b)
bool pairCompare_double( pair<int,double> a, pair<int,double> b)
{
return (a.second.preamble_delay_ms+a.second.prn_delay_ms) > (b.second.preamble_delay_ms+b.second.prn_delay_ms);
return (a.second) < (b.second);
}
void clearQueue( std::deque<double> &q )
{
std::deque<double> empty;
std::swap( q, empty );
}
int gps_l1_ca_observables_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) {
gnss_synchro **in = (gnss_synchro **) &input_items[0]; //Get the input samples pointer
gnss_synchro **in = (gnss_synchro **) &input_items[0]; //Get the input pointer
gnss_pseudorange **out = (gnss_pseudorange **) &output_items[0]; //Get the output pointer
// CONSTANTS TODO: place in a file
const float code_length_s=0.001; //1 ms
const float C_m_ms= GPS_C_m_s/1000.0; // The speed of light, [m/ms]
const float nav_sol_period_ms=1000;
//--- Find number of samples per spreading code ----------------------------
const signed int codeFreqBasis=1023000; //Hz
const signed int codeLength=1023;
const unsigned int samples_per_code = round(d_fs_in/ (codeFreqBasis / codeLength));
gnss_pseudorange current_gnss_pseudorange;
map<int,gnss_synchro> gps_words;
map<int,gnss_synchro>::iterator gps_words_iter;
map<int,float> pseudoranges;
map<int,float>::iterator pseudoranges_iter;
map<int,float> pseudoranges_dump;
map<int,double>::iterator current_prn_timestamps_ms_iter;
map<int,double> current_prn_timestamps_ms;
float min_preamble_delay_ms;
float max_preamble_delay_ms;
bool flag_valid_pseudoranges=false;
double min_preamble_delay_ms;
double max_preamble_delay_ms;
float pseudoranges_timestamp_ms;
float traveltime_ms;
float pseudorange_m;
double pseudoranges_timestamp_ms;
double traveltime_ms;
double pseudorange_m;
int history_shift=0;
double delta_timestamp_ms;
double min_delta_timestamp_ms;
double actual_min_prn_delay_ms;
double current_prn_delay_ms;
int pseudoranges_reference_sat_ID=0;
unsigned int pseudoranges_reference_sat_channel_ID=0;
d_sample_counter++; //count for the processed samples
bool flag_history_ok=true; //flag to indicate that all the queues have filled their timestamp history
/*!
* 1. Read the GNSS SYNCHRO objects from available channels to obtain the preamble timestamp, current PRN start time and accumulated carrier phase
*/
for (unsigned int i=0; i<d_nchannels ; i++)
{
if (in[i][0].valid_word) //if this channel have valid word
{
gps_words.insert(pair<int,gnss_synchro>(in[i][0].channel_ID,in[i][0])); //record the word structure in a map for pseudoranges
}
}
if(gps_words.size()>0)
{
// find the minimum index (nearest satellite, will be the reference)
gps_words_iter=min_element(gps_words.begin(),gps_words.end(),pairCompare_min);
min_preamble_delay_ms=gps_words_iter->second.preamble_delay_ms+gps_words_iter->second.prn_delay_ms; //[ms]
pseudoranges_timestamp_ms=min_preamble_delay_ms; //save the shortest pseudorange timestamp to compute the RINEX timestamp
pseudoranges_reference_sat_ID=gps_words_iter->second.satellite_PRN;
gps_words_iter=max_element(gps_words.begin(),gps_words.end(),pairCompare_max);
max_preamble_delay_ms=gps_words_iter->second.preamble_delay_ms; //[ms]
if ((max_preamble_delay_ms-min_preamble_delay_ms)<70) flag_valid_pseudoranges=true;
//compute the pseudoranges
for(gps_words_iter = gps_words.begin(); gps_words_iter != gps_words.end(); gps_words_iter++)
{
std::cout<<"prn_delay="<<gps_words_iter->second.prn_delay_ms<<std::endl;
traveltime_ms=gps_words_iter->second.preamble_delay_ms+gps_words_iter->second.prn_delay_ms-min_preamble_delay_ms+GPS_STARTOFFSET_ms; //[ms]
pseudorange_m=traveltime_ms*C_m_ms; // [m]
pseudoranges.insert(pair<int,float>(gps_words_iter->second.satellite_PRN,pseudorange_m)); //record the preamble index in a map
if (d_dump==true)
{
pseudoranges_dump.insert(pair<int,float>(gps_words_iter->second.channel_ID,pseudorange_m));
}
}
// write the pseudoranges to RINEX OBS file
// 1- need a valid clock
if (flag_valid_pseudoranges==true and d_last_nav_msg.d_satellite_PRN>0)
// RECORD PRN start timestamps history
if (d_history_prn_delay_ms[i].size()<MAX_TOA_DELAY_MS)
{
//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
d_ls_pvt->get_PVT(pseudoranges,d_ephemeris_clock_s+((double)pseudoranges_timestamp_ms-d_ephemeris_timestamp_ms)/1000.0);
d_history_prn_delay_ms[i].push_front(in[i][0].prn_delay_ms);
flag_history_ok=false; // at least one channel need more samples
}else{
//clearQueue(d_history_prn_delay_ms[i]); //clear the queue as the preamble arrives
d_history_prn_delay_ms[i].pop_back();
d_history_prn_delay_ms[i].push_front(in[i][0].prn_delay_ms);
}
}
//debug
cout << setprecision(16);
for(pseudoranges_iter = pseudoranges.begin();
pseudoranges_iter != pseudoranges.end();
pseudoranges_iter++)
{
cout<<"Pseudoranges =("<<pseudoranges_iter->first<<","<<pseudoranges_iter->second<<")"<<endl;
}
gps_navigation_message nav_msg;
if (d_nav_queue->try_pop(nav_msg)==true)
{
cout<<"New ephemeris record has arrived from SAT ID "<<nav_msg.d_satellite_PRN<<endl;
d_last_nav_msg=nav_msg;
d_ls_pvt->d_ephemeris[nav_msg.d_channel_ID]=nav_msg;
// **** update pseudoranges clock ****
if (nav_msg.d_satellite_PRN==pseudoranges_reference_sat_ID)
{
d_ephemeris_clock_s=d_last_nav_msg.d_TOW;
d_ephemeris_timestamp_ms=d_last_nav_msg.d_subframe1_timestamp_ms;
}
// **** write ephemeris to RINES NAV file
//d_rinex_printer.LogRinex2Nav(nav_msg);
}
if (d_dump==true)
/*!
* 1.2 Assume no satellites in tracking
*/
for (unsigned int i=0; i<d_nchannels ; i++)
{
float tmp_float=0.0;
for (int i=0;i<d_nchannels;i++)
{
pseudoranges_iter=pseudoranges_dump.find(i);
if (pseudoranges_iter!=pseudoranges_dump.end())
{
d_dump_file.write((char*)&pseudoranges_iter->second, sizeof(float));
}else{
d_dump_file.write((char*)&tmp_float, sizeof(float));
}
}
current_gnss_pseudorange.valid=false;
current_gnss_pseudorange.SV_ID=0;
current_gnss_pseudorange.pseudorange_m=0;
current_gnss_pseudorange.timestamp_ms=0;
*out[i]=current_gnss_pseudorange;
}
/*!
* 2. Compute RAW pseudorranges: Use only the valid channels (channels that are tracking a satellite)
*/
if(gps_words.size()>0 and flag_history_ok==true)
{
/*!
* 2.1 find the minimum preamble timestamp (nearest satellite, will be the reference)
*/
// The nearest satellite, first preamble to arrive
gps_words_iter=min_element(gps_words.begin(),gps_words.end(),pairCompare_gnss_synchro);
min_preamble_delay_ms=gps_words_iter->second.preamble_delay_ms; //[ms]
pseudoranges_reference_sat_ID=gps_words_iter->second.satellite_PRN; // it is the reference!
pseudoranges_reference_sat_channel_ID=gps_words_iter->second.channel_ID;
// The farthest satellite, last preamble to arrive
gps_words_iter=max_element(gps_words.begin(),gps_words.end(),pairCompare_gnss_synchro);
max_preamble_delay_ms=gps_words_iter->second.preamble_delay_ms;
min_delta_timestamp_ms=gps_words_iter->second.prn_delay_ms-max_preamble_delay_ms; //[ms]
// check if this is a valid set of observations
if ((max_preamble_delay_ms-min_preamble_delay_ms)<MAX_TOA_DELAY_MS)
{
// Now we have to determine were we are in time, compared with the last preamble! -> we select the corresponding history
/*!
* \todo Explain this better!
*/
//bool flag_preamble_navigation_now=true;
// find again the minimum CURRENT minimum preamble time, taking into account the preamble timeshift
for(gps_words_iter = gps_words.begin(); gps_words_iter != gps_words.end(); gps_words_iter++)
{
delta_timestamp_ms=(gps_words_iter->second.prn_delay_ms-gps_words_iter->second.preamble_delay_ms)-min_delta_timestamp_ms;
history_shift=round(delta_timestamp_ms);
//std::cout<<"history_shift="<<history_shift<<"\r\n";
current_prn_timestamps_ms.insert(pair<int,double>(gps_words_iter->second.channel_ID,d_history_prn_delay_ms[gps_words_iter->second.channel_ID][history_shift]));
// debug: preamble position test
//if ((d_history_prn_delay_ms[gps_words_iter->second.channel_ID][history_shift]-gps_words_iter->second.preamble_delay_ms)<0.1)
//{std::cout<<"ch "<<gps_words_iter->second.channel_ID<<" current_prn_time-last_preamble_prn_time="<<
// d_history_prn_delay_ms[gps_words_iter->second.channel_ID][history_shift]-gps_words_iter->second.preamble_delay_ms<<"\r\n";
//}else{
// flag_preamble_navigation_now=false;
//}
}
//if (flag_preamble_navigation_now==true)
//{
//std::cout<<"PREAMBLE NAVIGATION NOW!\r\n";
//d_sample_counter=0;
//}
current_prn_timestamps_ms_iter=min_element(current_prn_timestamps_ms.begin(),current_prn_timestamps_ms.end(),pairCompare_double);
actual_min_prn_delay_ms=current_prn_timestamps_ms_iter->second;
pseudoranges_timestamp_ms=actual_min_prn_delay_ms; //save the shortest pseudorange timestamp to compute the current GNSS timestamp
/*!
* 2.2 compute the pseudoranges
*/
for(gps_words_iter = gps_words.begin(); gps_words_iter != gps_words.end(); gps_words_iter++)
{
// #### compute the pseudorrange for this satellite ###
current_prn_delay_ms=current_prn_timestamps_ms.at(gps_words_iter->second.channel_ID);
traveltime_ms=current_prn_delay_ms-actual_min_prn_delay_ms+GPS_STARTOFFSET_ms; //[ms]
//std::cout<<"delta_time_ms="<<current_prn_delay_ms-actual_min_prn_delay_ms<<"\r\n";
pseudorange_m=traveltime_ms*GPS_C_m_ms; // [m]
// update the pseudorange object
current_gnss_pseudorange.pseudorange_m=pseudorange_m;
current_gnss_pseudorange.timestamp_ms=pseudoranges_timestamp_ms;
current_gnss_pseudorange.SV_ID=gps_words_iter->second.satellite_PRN;
current_gnss_pseudorange.valid=true;
// #### write the pseudorrange block output for this satellite ###
*out[gps_words_iter->second.channel_ID]=current_gnss_pseudorange;
}
}
}
if(d_dump==true) {
// MULTIPLEXED FILE RECORDING - Record results to file
try {
double tmp_double;
for (unsigned int i=0; i<d_nchannels ; i++)
{
tmp_double=in[i][0].preamble_delay_ms;
d_dump_file.write((char*)&tmp_double, sizeof(double));
tmp_double=in[i][0].prn_delay_ms;
d_dump_file.write((char*)&tmp_double, sizeof(double));
tmp_double=out[i][0].pseudorange_m;
d_dump_file.write((char*)&tmp_double, sizeof(double));
tmp_double=out[i][0].timestamp_ms;
d_dump_file.write((char*)&tmp_double, sizeof(double));
tmp_double=out[i][0].SV_ID;
d_dump_file.write((char*)&tmp_double, sizeof(double));
}
}
catch (std::ifstream::failure e) {
std::cout << "Exception writing observables dump file "<<e.what()<<"\r\n";
}
}
consume_each(1); //one by one
return 0;
if ((d_sample_counter%d_output_rate_ms)==0)
{
return 1; //Output the observables
}else{
return 0;//hold on
}
}

View File

@@ -1,11 +1,32 @@
/**
* Copyright notice
/*!
* \file gps_l1_ca_observables_cc.h
* \brief Pseudorange computation module for GPS L1 C/A
* \author Javier Arribas, 2011. jarribas(at)cttc.es
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
/**
* Author: Javier Arribas, 2011. jarribas(at)cttc.es
*/
#ifndef GPS_L1_CA_OBSERVABLES_CC_H
#define GPS_L1_CA_OBSERVABLES_CC_H
@@ -24,14 +45,13 @@
#include "gps_navigation_message.h"
#include "rinex_2_1_printer.h"
#include "gps_l1_ca_ls_pvt.h"
#include "GPS_L1_CA.h"
class gps_l1_ca_observables_cc;
typedef boost::shared_ptr<gps_l1_ca_observables_cc> gps_l1_ca_observables_cc_sptr;
gps_l1_ca_observables_cc_sptr
gps_l1_ca_make_observables_cc(unsigned int n_channels, gr_msg_queue_sptr queue, bool dump);
gps_l1_ca_make_observables_cc(unsigned int n_channels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging);
class gps_l1_ca_observables_cc : public gr_block {
@@ -39,32 +59,24 @@ class gps_l1_ca_observables_cc : public gr_block {
private:
friend gps_l1_ca_observables_cc_sptr
gps_l1_ca_make_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump);
gps_l1_ca_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump);
gps_l1_ca_make_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging);
gps_l1_ca_observables_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging);
// class private vars
gr_msg_queue_sptr d_queue;
bool d_dump;
bool d_flag_averaging;
long int d_sample_counter;
unsigned int d_nchannels;
unsigned long int d_fs_in;
int d_output_rate_ms;
std::string d_dump_filename;
std::ofstream d_dump_file;
std::deque<double> *d_history_prn_delay_ms;
concurrent_queue<gps_navigation_message> *d_nav_queue; // Navigation ephemeris queue
rinex_printer d_rinex_printer; // RINEX printer class
gps_navigation_message d_last_nav_msg; //last navigation message
double d_ephemeris_clock_s;
double d_ephemeris_timestamp_ms;
gps_l1_ca_ls_pvt *d_ls_pvt;
public:
~gps_l1_ca_observables_cc ();

View File

@@ -1,3 +1,2 @@
build-project adapters ;
build-project gnuradio_blocks ;
build-project libs ;
build-project gnuradio_blocks ;

View File

@@ -38,6 +38,8 @@
#include <string>
#include <iostream>
#include <fstream>
#include <glog/log_severity.h>
#include <glog/logging.h>
@@ -93,6 +95,34 @@ FileSignalSource::FileSignalSource(ConfigurationInterface* configuration,
= gr_make_file_source(item_size_, filename_.c_str(), repeat_);
DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")";
if (samples_==0)
{
/*!
* BUG workaround: The GNURadio file source does not stop the receiver after reaching the End of File.
* A possible solution is to compute the file lenght in samples using file size, excluding the last 100 milliseconds, and enable always the
* valve block
*/
std::ifstream file (filename_.c_str(), std::ios::in|std::ios::binary|std::ios::ate);
std::ifstream::pos_type size;
if (file.is_open())
{
size =file.tellg();
}else{
std::cout<<"file_signal_source: Unable to open the samples file "<<filename_.c_str()<<"\r\n";
LOG_AT_LEVEL(WARNING)<<"file_signal_source: Unable to open the samples file "<<filename_.c_str();
}
std::cout<<std::setprecision(16);
std::cout<<"Processing file "<<filename_<<" containing "<<(double)size<<" [bytes] \r\n";
if (size>0)
{
samples_=floor((double)size/(double)item_size())-ceil(0.1*(double)sampling_frequency_); //process all the samples available in the file excluding the last 100 ms
}
}
double signal_duration_s;
signal_duration_s=(double)samples_*(1/(double)sampling_frequency_);
DLOG(INFO)<<"Total samples to be processed="<<samples_<<" GNSS signal duration= "<<signal_duration_s<<" [s]";
std::cout<<"GNSS signal recorded time to be processed: "<<signal_duration_s<<" [s]\r\n";
// if samples != 0 then enable a flow valve to stop the process after n samples
if (samples_ != 0)
{

View File

@@ -66,22 +66,13 @@ GpsL1CaTelemetryDecoder::GpsL1CaTelemetryDecoder(ConfigurationInterface* configu
DLOG(INFO) << "role " << role;
DLOG(INFO) << "vector length " << vector_length_;
item_type_ = configuration->property(role + ".item_type", default_item_type);
vector_length_ = configuration->property(role + ".vector_length", 2048);
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); //unused!
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
int fs_in;
fs_in = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
if(item_type_.compare("gr_complex") == 0)
{
item_size_ = sizeof(gr_complex);
telemetry_decoder_ = gps_l1_ca_make_telemetry_decoder_cc(satellite_, 0, 0, vector_length_, queue_, dump_); // TODO fix me
}
else
{
LOG_AT_LEVEL(WARNING) << item_type_ << " unknown navigation item type.";
}
telemetry_decoder_ = gps_l1_ca_make_telemetry_decoder_cc(satellite_, 0, (long)fs_in, vector_length_, queue_, dump_); // TODO fix me
DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")";

View File

@@ -79,7 +79,7 @@ public:
size_t item_size()
{
return item_size_;
return 0;
}
private:
@@ -87,7 +87,6 @@ private:
int satellite_;
int channel_;
size_t item_size_;
unsigned int vector_length_;
std::string item_type_;

View File

@@ -1,19 +1,36 @@
/*!
* Navigation message demodulator based on the Kay Borre book MATLAB-based GPS receiver
* \file gps_l1_ca_telemetry_decoder_cc.cc
* \brief Navigation message demodulator based on the Kay Borre book MATLAB-based GPS receiver
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
/**
* Copyright notice
/*!
* \todo Clean this code and move the telemetri definitions to GPS_L1_CA system definitions file
*/
/**
* Author: Javier Arribas, 2011. jarribas(at)cttc.es
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gps_l1_ca_telemetry_decoder_cc.h"
#include "control_message_factory.h"
@@ -27,8 +44,11 @@
#include <glog/log_severity.h>
#include <glog/logging.h>
using google::LogMessage;
using google::LogMessage;
/*!
* \todo name and move the magic numbers to GPS_L1_CA.h
*/
gps_l1_ca_telemetry_decoder_cc_sptr
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) {
@@ -47,7 +67,7 @@ void gps_l1_ca_telemetry_decoder_cc::forecast (int noutput_items,
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) :
gr_block ("gps_navigation_cc", gr_make_io_signature (5, 5, sizeof(float)),
gr_block ("gps_navigation_cc", gr_make_io_signature (5, 5, sizeof(double)),
gr_make_io_signature(1, 1, sizeof(gnss_synchro))) {
// initialize internal vars
d_queue = queue;
@@ -55,6 +75,9 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(unsigned int sate
d_satellite = satellite;
d_vector_length = vector_length;
d_samples_per_bit=20; // it is exactly 1000*(1/50)=20
d_fs_in=fs_in;
d_preamble_duration_seconds=(1.0/(float)GPS_CA_TELEMETRY_RATE_BITS_SECOND)*(float)GPS_CA_PREAMBLE_LENGTH_BITS;
//std::cout<<"d_preamble_duration_seconds="<<d_preamble_duration_seconds<<"\r\n";
// set the preamble
unsigned short int preambles_bits[8]=GPS_PREAMBLE;
@@ -77,6 +100,7 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(unsigned int sate
}
}
d_sample_counter=0;
d_preamble_code_phase_seconds=0;
d_stat=0;
d_preamble_index=0;
d_symbol_accumulator_counter=0;
@@ -101,57 +125,88 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) {
int corr_value=0;
int preamble_diff;
gnss_synchro gps_synchro; //structure to save the synchronization information
gnss_synchro **out = (gnss_synchro **) &output_items[0];
d_sample_counter++; //count for the processed samples
const float **in = (const float **) &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 channel 0: Prompt correlator output Q
// *out[0]=(double)d_Prompt.real();
// // Output channel 1: Prompt correlator output I
// *out[1]=(double)d_Prompt.imag();
// // Output channel 2: PRN absolute delay [s]
// *out[2]=d_sample_counter_seconds;
// // Output channel 3: d_acc_carrier_phase_rad [rad]
// *out[3]=(double)d_acc_carrier_phase_rad;
// // Output channel 4: PRN code phase [s]
// *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
*/
// FIFO history to get the exact timestamp of the first symbol of the preamble
// if (d_prn_start_sample_history.size()<160)
// {
// // fill the queue
// d_prn_start_sample_history.push_front(in[2][0]);
// consume_each(1); //one by one
// return 1;
// }else{
// d_prn_start_sample_history.pop_back();
// d_prn_start_sample_history.push_front(in[2][0]);
// }
// TODO Optimize me!
//******* preamble correlation ********
for (unsigned int i=0;i<d_samples_per_bit*8;i++){
if (in[1][i] <= 0) // symbols clipping
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<<"Pre-detection SAT "<<this->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_preamble_index=d_sample_counter;//record the preamble sample stamp (t_P)
d_preamble_phase=in[2][0]; //record the PRN start sample index associated to the preamble
//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 "<<this->d_satellite<<" with preamble start at "<<in[2][0]<<" [ms]"<<std::endl;
}
}else
{
if (preamble_diff>7000){
std::cout<<"lost of frame sync SAT "<<this->d_satellite<<std::endl;
d_stat=0; //lost of frame sync
d_flag_frame_sync=false;
}
}
}
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 *****
@@ -194,7 +249,7 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
}
if (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_phase;
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{
@@ -209,21 +264,18 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
}
// output the frame
consume_each(1); //one by one
consume_each(1); //one by one
if ((d_sample_counter%NAVIGATION_OUTPUT_RATE_MS)==0)
{
gps_synchro.valid_word=(d_flag_frame_sync==true and d_flag_parity==true);
//gps_synchro.preamble_delay_ms=(float)d_preamble_index;
gps_synchro.preamble_delay_ms=(float)d_preamble_index;
gps_synchro.prn_delay_ms=in[3][0];
gps_synchro.satellite_PRN=d_satellite;
gps_synchro.channel_ID=d_channel;
*out[0]=gps_synchro;
return 1;
}else{
return 0;
}
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;
}

View File

@@ -1,12 +1,31 @@
/**
* Copyright notice
/*!
* \file gps_l1_ca_telemetry_decoder_cc.h
* \brief Navigation message demodulator based on the Kay Borre book MATLAB-based GPS receiver
* \author Javier Arribas, 2011. jarribas(at)cttc.es
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
/**
* Author: Javier Arribas, 2011. jarribas(at)cttc.es
*/
#ifndef GPS_L1_CA_TELEMETRY_DECODER_CC_H
#define GPS_L1_CA_TELEMETRY_DECODER_CC_H
@@ -63,8 +82,11 @@ private:
unsigned int d_GPS_frame_4bytes;
unsigned int d_prev_GPS_frame_4bytes;
bool d_flag_parity;
bool d_flag_preamble;
int d_word_number;
long d_fs_in;
double d_preamble_duration_seconds;
// navigation message vars
gps_navigation_message d_nav;
GpsL1CaSubframeFsm d_GPS_FSM;
@@ -76,7 +98,10 @@ private:
int d_satellite;
int d_channel;
float d_preamble_phase;
//std::deque<double> d_prn_start_sample_history;
double d_preamble_time_seconds;
double d_preamble_code_phase_seconds;
std::string d_dump_filename;
std::ofstream d_dump_file;

View File

@@ -144,16 +144,17 @@ void GpsL1CaSubframeFsm::gps_subframe_to_nav_msg()
{
int subframe_ID;
// NEW GPS SUBFRAME HAS ARRIVED!
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;
d_nav.d_satellite_PRN=d_satellite_PRN;
d_nav.d_channel_ID=d_channel_ID;
if (subframe_ID==1) {
d_nav.d_subframe1_timestamp_ms=this->d_preamble_time_ms-6002;
std::cout<<"FSM: set subframe1 preamble timestamp for sat "<<d_nav.d_satellite_PRN<<std::endl;
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;
}
//TODO: change to subframe 5
/*!
* \todo change satellite validation to subframe 5 because it will have a complete set of ephemeris parameters
*/
if (subframe_ID==3) { // if the subframe is the 5th, then
if (d_nav.satellite_validation()) // if all the satellite ephemeris parameters are good, then
{

View File

@@ -34,7 +34,7 @@
*/
#include "gps_l1_ca_dll_fll_pll_tracking.h"
#include "GPS_L1_CA.h"
#include "configuration_interface.h"
#include <gnuradio/gr_io_signature.h>
@@ -71,8 +71,8 @@ GpsL1CaDllFllPllTracking::GpsL1CaDllFllPllTracking(
int order;
item_type = configuration->property(role + ".item_type",default_item_type);
vector_length = configuration->property(role + ".vector_length", 2048);
fs_in = configuration->property(role + ".fs_in", 2048000);
//vector_length = configuration->property(role + ".vector_length", 2048);
fs_in = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
f_if = configuration->property(role + ".if", 0);
dump = configuration->property(role + ".dump", false);
order = configuration->property(role + ".order", 2);
@@ -81,16 +81,18 @@ GpsL1CaDllFllPllTracking::GpsL1CaDllFllPllTracking(
dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0);
early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5);
std::string default_dump_filename = "./tracking.dat";
std::string default_dump_filename = "./track_ch";
dump_filename = configuration->property(role + ".dump_filename",
default_dump_filename); //unused!
vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
//################# MAKE TRACKING GNURadio object ###################
if (item_type.compare("gr_complex") == 0)
{
item_size_ = sizeof(gr_complex);
tracking_ = gps_l1_ca_dll_fll_pll_make_tracking_cc(satellite_, f_if,
fs_in, vector_length, queue_, dump, order, fll_bw_hz, pll_bw_hz,dll_bw_hz,early_late_space_chips);
fs_in, vector_length, queue_, dump, dump_filename, order, fll_bw_hz, pll_bw_hz,dll_bw_hz,early_late_space_chips);
}
else
{

View File

@@ -34,7 +34,7 @@
*/
#include "gps_l1_ca_dll_pll_tracking.h"
#include "GPS_L1_CA.h"
#include "configuration_interface.h"
#include <gnuradio/gr_io_signature.h>
@@ -69,24 +69,26 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking(
float early_late_space_chips;
item_type = configuration->property(role + ".item_type",default_item_type);
vector_length = configuration->property(role + ".vector_length", 2048);
fs_in = configuration->property(role + ".fs_in", 2048000);
//vector_length = configuration->property(role + ".vector_length", 2048);
fs_in = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
f_if = configuration->property(role + ".if", 0);
dump = configuration->property(role + ".dump", false);
pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0);
dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0);
early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5);
std::string default_dump_filename = "./tracking.dat";
std::string default_dump_filename = "./track_ch";
dump_filename = configuration->property(role + ".dump_filename",
default_dump_filename); //unused!
vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
//################# MAKE TRACKING GNURadio object ###################
if (item_type.compare("gr_complex") == 0)
{
item_size_ = sizeof(gr_complex);
tracking_ = gps_l1_ca_dll_pll_make_tracking_cc(satellite_, f_if,
fs_in, vector_length, queue_, dump,pll_bw_hz,dll_bw_hz,early_late_space_chips);
fs_in, vector_length, queue_, dump, dump_filename, pll_bw_hz,dll_bw_hz,early_late_space_chips);
}
else
{

View File

@@ -56,15 +56,17 @@
* \todo Include in definition header file
*/
#define CN0_ESTIMATION_SAMPLES 10
#define MINIMUM_VALID_CN0 25
#define MAXIMUM_LOCK_FAIL_COUNTER 200
using google::LogMessage;
gps_l1_ca_dll_fll_pll_tracking_cc_sptr
gps_l1_ca_dll_fll_pll_make_tracking_cc(unsigned int satellite, long if_freq, long fs_in, unsigned
int vector_length, gr_msg_queue_sptr queue, bool dump, int order, float fll_bw_hz, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) {
int vector_length, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int order, float fll_bw_hz, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) {
return gps_l1_ca_dll_fll_pll_tracking_cc_sptr(new gps_l1_ca_dll_fll_pll_tracking_cc(satellite, if_freq,
fs_in, vector_length, queue, dump, order, fll_bw_hz, pll_bw_hz,dll_bw_hz,early_late_space_chips));
fs_in, vector_length, queue, dump, dump_filename, order, fll_bw_hz, pll_bw_hz,dll_bw_hz,early_late_space_chips));
}
void gps_l1_ca_dll_fll_pll_tracking_cc::forecast (int noutput_items,
@@ -73,9 +75,9 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::forecast (int noutput_items,
}
gps_l1_ca_dll_fll_pll_tracking_cc::gps_l1_ca_dll_fll_pll_tracking_cc(unsigned int satellite, long if_freq, long fs_in, unsigned
int vector_length, gr_msg_queue_sptr queue, bool dump, int order, float fll_bw_hz, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) :
int vector_length, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int order, float fll_bw_hz, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) :
gr_block ("gps_l1_ca_dll_fll_pll_tracking_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)),
gr_make_io_signature(5, 5, sizeof(float))) {
gr_make_io_signature(5, 5, sizeof(double))) {
//gr_sync_decimator ("gps_l1_ca_dll_pll_tracking_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)),
// gr_make_io_signature(3, 3, sizeof(float)),vector_length) {
// initialize internal vars
@@ -86,6 +88,7 @@ gps_l1_ca_dll_fll_pll_tracking_cc::gps_l1_ca_dll_fll_pll_tracking_cc(unsigned in
d_fs_in = fs_in;
d_vector_length = vector_length;
d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips)
d_dump_filename=dump_filename;
// Initialize tracking variables ==========================================
d_carrier_loop_filter.set_params(fll_bw_hz,pll_bw_hz,order);
@@ -101,6 +104,7 @@ gps_l1_ca_dll_fll_pll_tracking_cc::gps_l1_ca_dll_fll_pll_tracking_cc(unsigned in
// sample synchronization
d_sample_counter=0;
d_sample_counter_seconds=0;
d_acq_sample_stamp=0;
d_last_seg=0;// this is for debug output only
@@ -125,8 +129,9 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::start_tracking(){
*/
unsigned long int acq_trk_diff_samples;
float acq_trk_diff_seconds;
acq_trk_diff_samples=d_sample_counter-d_acq_sample_stamp-d_vector_length;
acq_trk_diff_seconds=acq_trk_diff_samples/(float)d_fs_in;
acq_trk_diff_samples=d_sample_counter-d_acq_sample_stamp;//-d_vector_length;
//std::cout<<"acq_trk_diff_samples="<<acq_trk_diff_samples<<"\r\n";
acq_trk_diff_seconds=(float)acq_trk_diff_samples/(float)d_fs_in;
//doppler effect
// Fd=(C/(C+Vr))*F
float radial_velocity;
@@ -140,15 +145,24 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::start_tracking(){
T_prn_mod_seconds=T_chip_mod_seconds*GPS_L1_CA_CODE_LENGTH_CHIPS;
T_prn_mod_samples=T_prn_mod_seconds*(float)d_fs_in;
d_next_prn_length_samples=round(T_prn_mod_samples);
//compute the code phase chips prediction
float delta_T_prn_samples;
float delay_correction_samples;
delta_T_prn_samples=fmod((float)acq_trk_diff_samples,T_prn_mod_samples);
delay_correction_samples=T_prn_mod_samples-delta_T_prn_samples;
d_acq_code_phase_samples=d_acq_code_phase_samples-delay_correction_samples;
if (d_acq_code_phase_samples<0){
d_acq_code_phase_samples=d_acq_code_phase_samples+T_prn_mod_samples;
}
float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS/GPS_L1_CA_CODE_RATE_HZ;
float T_prn_true_samples = T_prn_true_seconds*(float)d_fs_in;
float T_prn_diff_seconds;
T_prn_diff_seconds=T_prn_true_seconds-T_prn_mod_seconds;
float N_prn_diff;
N_prn_diff=acq_trk_diff_seconds/T_prn_true_seconds;
float corrected_acq_phase_samples,delay_correction_samples;
corrected_acq_phase_samples=fmod((d_acq_code_phase_samples+T_prn_diff_seconds*N_prn_diff*(float)d_fs_in),T_prn_true_samples);
if (corrected_acq_phase_samples<0)
{
corrected_acq_phase_samples=T_prn_mod_samples+corrected_acq_phase_samples;
}
delay_correction_samples=d_acq_code_phase_samples-corrected_acq_phase_samples;
d_acq_code_phase_samples=corrected_acq_phase_samples;
d_carrier_doppler_hz=d_acq_carrier_doppler_hz;
// DLL/PLL filter initialization
d_carrier_loop_filter.initialize(d_acq_carrier_doppler_hz);
@@ -168,24 +182,8 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::start_tracking(){
d_next_rem_code_phase_samples=0;
d_acc_carrier_phase_rad=0;
// ############# ENABLE DATA FILE LOG #################
if (d_dump==true)
{
if (d_dump_file.is_open()==false)
{
try {
d_dump_filename="track_ch"; //base path and name for the tracking log file
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
d_dump_filename.append(".dat");
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
std::cout<<"Tracking dump enabled on channel "<<d_channel<<" Log file: "<<d_dump_filename.c_str()<<std::endl;
}
catch (std::ifstream::failure e) {
std::cout << "channel "<<d_channel <<" Exception opening trk dump file "<<e.what()<<"\r\n";
}
}
}
d_code_phase_samples = d_acq_code_phase_samples;
// DEBUG OUTPUT
std::cout<<"Tracking start on channel "<<d_channel<<" for satellite ID* "<< this->d_satellite<< std::endl;
DLOG(INFO) << "Start tracking for satellite "<<this->d_satellite<<" received ";
@@ -194,7 +192,7 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::start_tracking(){
d_pull_in=true;
d_enable_tracking=true;
std::cout<<"PULL-IN Doppler [Hz]= "<<d_carrier_doppler_hz<<" PULL-IN Code Phase [chips]= "<<d_acq_code_phase_samples<<"\r\n";
std::cout<<"PULL-IN Doppler [Hz]= "<<d_carrier_doppler_hz<<" Code Phase correction [samples]="<<delay_correction_samples<<" PULL-IN Code Phase [samples]= "<<d_acq_code_phase_samples<<"\r\n";
}
void gps_l1_ca_dll_fll_pll_tracking_cc::update_local_code()
@@ -218,12 +216,13 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::update_local_code()
d_late_code[i] = d_ca_code[associated_chip_index];
tcode_chips=tcode_chips+code_phase_step_chips;
}
//d_code_phase_samples=d_code_phase_samples+(float)d_fs_in*GPS_L1_CA_CODE_LENGTH_CHIPS*(1/d_code_freq_hz-1/GPS_L1_CA_CODE_RATE_HZ);
}
void gps_l1_ca_dll_fll_pll_tracking_cc::update_local_carrier()
{
float phase, phase_step;
phase_step = (float)TWO_PI*d_carrier_doppler_hz/d_fs_in;
phase_step = (float)TWO_PI*d_carrier_doppler_hz/(float)d_fs_in;
phase=d_rem_carr_phase;
for(int i = 0; i < d_current_prn_length_samples; i++) {
d_carr_sign[i] = gr_complex(cos(phase),sin(phase));
@@ -235,12 +234,12 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::update_local_carrier()
gps_l1_ca_dll_fll_pll_tracking_cc::~gps_l1_ca_dll_fll_pll_tracking_cc() {
d_dump_file.close();
delete d_ca_code;
delete d_early_code;
delete d_prompt_code;
delete d_late_code;
delete d_carr_sign;
delete d_Prompt_buffer;
delete[] d_ca_code;
delete[] d_early_code;
delete[] d_prompt_code;
delete[] d_late_code;
delete[] d_carr_sign;
delete[] d_Prompt_buffer;
}
/*! Tracking signal processing
@@ -250,23 +249,63 @@ gps_l1_ca_dll_fll_pll_tracking_cc::~gps_l1_ca_dll_fll_pll_tracking_cc() {
int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) {
// if ((unsigned int)ninput_items[0]<(d_vector_length*2))
// {
// std::cout<<"End of signal detected\r\n";
// const int samples_available = ninput_items[0];
// consume_each(samples_available);
// return 0;
// }
// process vars
float code_error_chips=0;
float correlation_time_s=0;
float PLL_discriminator_hz=0;
float carr_nco_hz=0;
d_Prompt_prev=d_Prompt; // for the FLL discriminator
d_Early=gr_complex(0,0);
d_Prompt=gr_complex(0,0);
d_Late=gr_complex(0,0);
if (d_enable_tracking==true){
/*!
* Receiver signal alignment
*/
if (d_pull_in==true)
{
int samples_offset=round(d_acq_code_phase_samples);
d_sample_counter+=samples_offset; //count for the processed samples
int samples_offset;
// 28/11/2011 ACQ to TRK transition BUG CORRECTION
float acq_trk_shif_correction_samples;
int acq_to_trk_delay_samples;
acq_to_trk_delay_samples=d_sample_counter-d_acq_sample_stamp;
acq_trk_shif_correction_samples=d_next_prn_length_samples-fmod((float)acq_to_trk_delay_samples,(float)d_next_prn_length_samples);
//std::cout<<"acq_trk_shif_correction="<<acq_trk_shif_correction_samples<<"\r\n";
samples_offset=round(d_acq_code_phase_samples+acq_trk_shif_correction_samples);
// /todo: Check if the sample counter sent to the next block as a time reference should be incremented AFTER sended or BEFORE
d_sample_counter_seconds = d_sample_counter_seconds + (((double)samples_offset)/(double)d_fs_in);
d_sample_counter=d_sample_counter+samples_offset; //count for the processed samples
d_pull_in=false;
std::cout<<" samples_offset "<<samples_offset<<"\r\n";
//std::cout<<" samples_offset="<<samples_offset<<"\r\n";
consume_each(samples_offset); //shift input to perform alignement with local replica
return 1;
}
// get the sample in and out pointers
const gr_complex* in = (gr_complex*) input_items[0]; //block input samples pointer
float **out = (float **) &output_items[0]; //block output streams pointer
double **out = (double **) &output_items[0]; //block output streams pointer
// check for samples consistency
for(int i=0;i<d_current_prn_length_samples;i++) {
if (std::isnan(in[i].real())==true or std::isnan(in[i].imag())==true)// or std::isinf(in[i].real())==true or std::isinf(in[i].imag())==true)
{
const int samples_available= ninput_items[0];
d_sample_counter=d_sample_counter+samples_available;
LOG_AT_LEVEL(WARNING) << "Detected NaN samples at sample number "<<d_sample_counter;
consume_each(samples_available);
return 0;
}
}
// Update the prn length based on code freq (variable) and
// sampling frequency (fixed)
// variable code PRN sample block size
@@ -277,11 +316,6 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto
gr_complex bb_signal_sample(0,0);
d_Prompt_prev=d_Prompt; // for the FLL discriminator
d_Early=gr_complex(0,0);
d_Prompt=gr_complex(0,0);
d_Late=gr_complex(0,0);
// perform Early, Prompt and Late correlation
/*!
* \todo Use SIMD-enabled correlators
@@ -299,11 +333,9 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto
* DLL, FLL, and PLL discriminators
*/
// Compute DLL error
float code_error_chips;
code_error_chips=dll_nc_e_minus_l_normalized(d_Early,d_Late);
//compute FLL error
float correlation_time_s;
correlation_time_s=((float)d_current_prn_length_samples)/(float)d_fs_in;
if (d_FLL_wait==1)
{
@@ -316,9 +348,7 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto
}
// Compute PLL error
float PLL_discriminator_hz;
PLL_discriminator_hz=pll_cloop_two_quadrant_atan(d_Prompt)/(float)TWO_PI;
//PLL_discriminator_hz=pll_four_quadrant_atan(d_Prompt)/(float)TWO_PI;
/*!
* \todo Update FLL assistance algorithm!
@@ -330,11 +360,13 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto
/*!
* DLL and FLL+PLL filter and get current carrier Doppler and code frequency
*/
float carr_nco_hz;
carr_nco_hz=d_carrier_loop_filter.get_carrier_error(d_FLL_discriminator_hz,PLL_discriminator_hz,correlation_time_s);
d_carrier_doppler_hz = (float)d_if_freq + carr_nco_hz;
d_code_freq_hz= GPS_L1_CA_CODE_RATE_HZ- (((d_carrier_doppler_hz - (float)d_if_freq)*GPS_L1_CA_CODE_RATE_HZ)/GPS_L1_FREQ_HZ)-code_error_chips;
/*!
* \todo Improve the lock detection algorithm!
*/
// ####### CN0 ESTIMATION AND LOCK DETECTORS ######
if (d_cn0_estimation_counter<CN0_ESTIMATION_SAMPLES)
{
@@ -347,13 +379,13 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto
d_carrier_lock_test=carrier_lock_detector(d_Prompt_buffer,CN0_ESTIMATION_SAMPLES);
// ###### TRACKING UNLOCK NOTIFICATION #####
int tracking_message;
if (d_carrier_lock_test<d_carrier_lock_threshold or d_carrier_lock_test>30)
if (d_carrier_lock_test<d_carrier_lock_threshold or d_carrier_lock_test>MINIMUM_VALID_CN0)
{
d_carrier_lock_fail_counter++;
}else{
if (d_carrier_lock_fail_counter>0) d_carrier_lock_fail_counter--;
}
if (d_carrier_lock_fail_counter>300)
if (d_carrier_lock_fail_counter>MAXIMUM_LOCK_FAIL_COUNTER)
{
std::cout<<"Channel "<<d_channel << " loss of lock!\r\n";
tracking_message=3; //loss of lock
@@ -365,67 +397,20 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto
//std::cout<<"d_carrier_lock_fail_counter"<<d_carrier_lock_fail_counter<<"\r\n";
}
/*!
* \todo Output the CN0
*/
// ########### Output the tracking data to navigation and PVT ##########
// Output channel 1: Prompt correlator output Q
*out[0]=d_Early.real();
// Output channel 2: Prompt correlator output I
*out[1]=d_Early.imag();
// Output channel 3: PRN absolute delay [ms]
*out[2]=(float)(((double)d_sample_counter/(double)d_fs_in)*1000.0);
// Output channel 4: PRN code error [ms]
*out[3]=d_acc_carrier_phase_rad;
if(d_dump) {
// MULTIPLEXED FILE RECORDING - Record results to file
float prompt_I;
float prompt_Q;
float tmp_E,tmp_P,tmp_L;
float tmp_float;
prompt_I=d_Prompt.imag();
prompt_Q=d_Prompt.real();
tmp_E=std::abs<float>(d_Early);
tmp_P=std::abs<float>(d_Prompt);
tmp_L=std::abs<float>(d_Late);
try {
// EPR
d_dump_file.write((char*)&tmp_E, sizeof(float));
d_dump_file.write((char*)&tmp_P, sizeof(float));
d_dump_file.write((char*)&tmp_L, sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write((char*)&prompt_I, sizeof(float));
d_dump_file.write((char*)&prompt_Q, sizeof(float));
// PRN start sample stamp
tmp_float=(float)d_sample_counter;
d_dump_file.write((char*)&tmp_float, sizeof(float));
// accumulated carrier phase
d_dump_file.write((char*)&d_acc_carrier_phase_rad, sizeof(float));
// carrier and code frequency
d_dump_file.write((char*)&d_carrier_doppler_hz, sizeof(float));
d_dump_file.write((char*)&d_code_freq_hz, sizeof(float));
//PLL commands
d_dump_file.write((char*)&PLL_discriminator_hz, sizeof(float));
d_dump_file.write((char*)&carr_nco_hz, sizeof(float));
//DLL commands
d_dump_file.write((char*)&code_error_chips, sizeof(float));
d_dump_file.write((char*)&code_error_chips, sizeof(float));
// CN0 and carrier lock test
d_dump_file.write((char*)&d_CN0_SNV_dB_Hz, sizeof(float));
d_dump_file.write((char*)&d_carrier_lock_test, sizeof(float));
// AUX vars (for debug purposes)
tmp_float=d_FLL_discriminator_hz;
d_dump_file.write((char*)&tmp_float, sizeof(float));
tmp_float=0.0;
d_dump_file.write((char*)&tmp_float, sizeof(float));
}
catch (std::ifstream::failure e) {
std::cout << "Exception writing trk dump file "<<e.what()<<"\r\n";
}
}
// Output channel 0: Prompt correlator output Q
*out[0]=(double)d_Prompt.real();
// Output channel 1: Prompt correlator output I
*out[1]=(double)d_Prompt.imag();
// Output channel 2: PRN absolute delay [s]
*out[2]=d_sample_counter_seconds;
// Output channel 3: d_acc_carrier_phase_rad [rad]
*out[3]=(double)d_acc_carrier_phase_rad;
// Output channel 4: PRN code phase [s]
*out[4]=(double)d_code_phase_samples*(1/(float)d_fs_in);
// ########## DEBUG OUTPUT
/*!
@@ -437,50 +422,115 @@ int gps_l1_ca_dll_fll_pll_tracking_cc::general_work (int noutput_items, gr_vecto
if (floor(d_sample_counter/d_fs_in)!=d_last_seg)
{
d_last_seg=floor(d_sample_counter/d_fs_in);
std::cout<<"t="<<d_last_seg<<std::endl;
std::cout<<"TRK CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<< std::endl;
std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl;
std::cout<<"Current input signal time="<<d_last_seg<<" [s]"<<std::endl;
std::cout<<"Tracking CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<<" [dB-Hz]"<<std::endl;
//std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl;
//if (d_last_seg==5) d_carrier_lock_fail_counter=500; //DEBUG: force unlock!
}
}else
{
if (floor(d_sample_counter/d_fs_in)!=d_last_seg)
{
d_last_seg=floor(d_sample_counter/d_fs_in);
std::cout<<"TRK CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<< std::endl;
std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl;
std::cout<<"Tracking CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<<" [dB-Hz]"<<std::endl;
//std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl;
}
}
//predict the next loop PRN period length prediction
//float T_chip_seconds,T_prn_seconds,T_prn_samples;
//T_chip_seconds=1/d_code_freq_hz;
//T_prn_seconds=T_chip_seconds*GPS_L1_CA_CODE_LENGTH_CHIPS-d_rem_code_phase_chips*T_chip_seconds;
//T_prn_samples=T_prn_seconds*(float)d_fs_in;
//d_next_prn_length_samples=round(T_prn_samples);
float T_chip_seconds;
float T_prn_seconds;
float T_prn_samples;
float K_blk_samples;
T_chip_seconds=1/d_code_freq_hz;
T_prn_seconds=T_chip_seconds*GPS_L1_CA_CODE_LENGTH_CHIPS;
T_prn_samples=T_prn_seconds*d_fs_in;
T_prn_samples=T_prn_seconds*(float)d_fs_in;
d_rem_code_phase_samples=d_next_rem_code_phase_samples;
K_blk_samples=T_prn_samples+d_rem_code_phase_samples;
d_next_prn_length_samples=round(K_blk_samples);
d_next_rem_code_phase_samples=K_blk_samples-d_next_prn_length_samples;
// Update the current PRN delay (code phase in samples)
float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS/GPS_L1_CA_CODE_RATE_HZ;
float T_prn_true_samples = T_prn_true_seconds*(float)d_fs_in;
d_code_phase_samples=d_code_phase_samples+T_prn_samples-T_prn_true_samples;
if (d_code_phase_samples<0)
{
d_code_phase_samples=T_prn_true_samples+d_code_phase_samples;
}
d_code_phase_samples=fmod(d_code_phase_samples,T_prn_true_samples);
d_next_prn_length_samples=round(K_blk_samples);//round to a discrete samples
d_next_rem_code_phase_samples=K_blk_samples-d_next_prn_length_samples; //rounding error
}else{
double **out = (double **) &output_items[0]; //block output streams pointer
*out[0]=0;
*out[1]=0;
*out[2]=0;
*out[3]=0;
*out[4]=0;
}
if(d_dump) {
// MULTIPLEXED FILE RECORDING - Record results to file
float prompt_I;
float prompt_Q;
float tmp_E,tmp_P,tmp_L;
float tmp_float;
prompt_I=d_Prompt.imag();
prompt_Q=d_Prompt.real();
tmp_E=std::abs<float>(d_Early);
tmp_P=std::abs<float>(d_Prompt);
tmp_L=std::abs<float>(d_Late);
try {
// EPR
d_dump_file.write((char*)&tmp_E, sizeof(float));
d_dump_file.write((char*)&tmp_P, sizeof(float));
d_dump_file.write((char*)&tmp_L, sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write((char*)&prompt_I, sizeof(float));
d_dump_file.write((char*)&prompt_Q, sizeof(float));
// PRN start sample stamp
//tmp_float=(float)d_sample_counter;
d_dump_file.write((char*)&d_sample_counter, sizeof(unsigned long int));
// accumulated carrier phase
d_dump_file.write((char*)&d_acc_carrier_phase_rad, sizeof(float));
// carrier and code frequency
d_dump_file.write((char*)&d_carrier_doppler_hz, sizeof(float));
d_dump_file.write((char*)&d_code_freq_hz, sizeof(float));
//PLL commands
d_dump_file.write((char*)&PLL_discriminator_hz, sizeof(float));
d_dump_file.write((char*)&carr_nco_hz, sizeof(float));
//DLL commands
d_dump_file.write((char*)&code_error_chips, sizeof(float));
d_dump_file.write((char*)&d_code_phase_samples, sizeof(float));
// CN0 and carrier lock test
d_dump_file.write((char*)&d_CN0_SNV_dB_Hz, sizeof(float));
d_dump_file.write((char*)&d_carrier_lock_test, sizeof(float));
// AUX vars (for debug purposes)
tmp_float=0;
d_dump_file.write((char*)&tmp_float, sizeof(float));
d_dump_file.write((char*)&d_sample_counter_seconds, sizeof(double));
}
catch (std::ifstream::failure e) {
std::cout << "Exception writing trk dump file "<<e.what()<<"\r\n";
}
}
consume_each(d_current_prn_length_samples); // this is necesary in gr_block derivates
d_sample_counter_seconds = d_sample_counter_seconds + (((double)d_current_prn_length_samples)/(double)d_fs_in);
d_sample_counter+=d_current_prn_length_samples; //count for the processed samples
return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false
}
void gps_l1_ca_dll_fll_pll_tracking_cc::set_acq_code_phase(float code_phase) {
d_acq_code_phase_samples = code_phase;
d_acq_code_phase_samples=code_phase;
LOG_AT_LEVEL(INFO) << "Tracking code phase set to " << d_acq_code_phase_samples;
}
@@ -497,6 +547,23 @@ void gps_l1_ca_dll_fll_pll_tracking_cc::set_satellite(unsigned int satellite) {
void gps_l1_ca_dll_fll_pll_tracking_cc::set_channel(unsigned int channel) {
d_channel = channel;
LOG_AT_LEVEL(INFO) << "Tracking Channel set to " << d_channel;
// ############# ENABLE DATA FILE LOG #################
if (d_dump==true)
{
if (d_dump_file.is_open()==false)
{
try {
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
d_dump_filename.append(".dat");
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
std::cout<<"Tracking dump enabled on channel "<<d_channel<<" Log file: "<<d_dump_filename.c_str()<<std::endl;
}
catch (std::ifstream::failure e) {
std::cout << "channel "<<d_channel <<" Exception opening trk dump file "<<e.what()<<"\r\n";
}
}
}
}
void gps_l1_ca_dll_fll_pll_tracking_cc::set_acq_sample_stamp(unsigned long int sample_stamp)

View File

@@ -62,6 +62,7 @@ gps_l1_ca_dll_fll_pll_make_tracking_cc(unsigned int satellite,
unsigned int vector_length,
gr_msg_queue_sptr queue,
bool dump,
std::string dump_filename,
int order,
float fll_bw_hz,
float pll_bw_hz,
@@ -81,6 +82,7 @@ private:
int vector_length,
gr_msg_queue_sptr queue,
bool dump,
std::string dump_filename,
int order,
float fll_bw_hz,
float pll_bw_hz,
@@ -93,6 +95,7 @@ private:
int vector_length,
gr_msg_queue_sptr queue,
bool dump,
std::string dump_filename,
int order,
float fll_bw_hz,
float pll_bw_hz,
@@ -130,6 +133,7 @@ private:
float d_carrier_doppler_hz;
float d_code_freq_hz;
float d_code_phase_samples;
int d_current_prn_length_samples;
int d_next_prn_length_samples;
int d_FLL_wait;
@@ -148,6 +152,8 @@ private:
float d_acc_carrier_phase_rad;
unsigned long int d_sample_counter;
double d_sample_counter_seconds;
unsigned long int d_acq_sample_stamp;
// CN0 estimation and lock detector

View File

@@ -55,15 +55,18 @@
* \todo Include in definition header file
*/
#define CN0_ESTIMATION_SAMPLES 10
#define MINIMUM_VALID_CN0 25
#define MAXIMUM_LOCK_FAIL_COUNTER 200
using google::LogMessage;
gps_l1_ca_dll_pll_tracking_cc_sptr
gps_l1_ca_dll_pll_make_tracking_cc(unsigned int satellite, long if_freq, long fs_in, unsigned
int vector_length, gr_msg_queue_sptr queue, bool dump, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) {
int vector_length, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) {
return gps_l1_ca_dll_pll_tracking_cc_sptr(new gps_l1_ca_dll_pll_tracking_cc(satellite, if_freq,
fs_in, vector_length, queue, dump, pll_bw_hz, dll_bw_hz, early_late_space_chips));
fs_in, vector_length, queue, dump, dump_filename, pll_bw_hz, dll_bw_hz, early_late_space_chips));
}
void gps_l1_ca_dll_pll_tracking_cc::forecast (int noutput_items,
@@ -72,9 +75,9 @@ void gps_l1_ca_dll_pll_tracking_cc::forecast (int noutput_items,
}
gps_l1_ca_dll_pll_tracking_cc::gps_l1_ca_dll_pll_tracking_cc(unsigned int satellite, long if_freq, long fs_in, unsigned
int vector_length, gr_msg_queue_sptr queue, bool dump, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) :
int vector_length, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float early_late_space_chips) :
gr_block ("gps_l1_ca_dll_pll_tracking_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)),
gr_make_io_signature(5, 5, sizeof(float))) {
gr_make_io_signature(5, 5, sizeof(double))) {
//gr_sync_decimator ("gps_l1_ca_dll_pll_tracking_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)),
// gr_make_io_signature(3, 3, sizeof(float)),vector_length) {
@@ -85,8 +88,7 @@ gps_l1_ca_dll_pll_tracking_cc::gps_l1_ca_dll_pll_tracking_cc(unsigned int satell
d_if_freq = if_freq;
d_fs_in = fs_in;
d_vector_length = vector_length;
//std::cout<<"pll_bw_hz= "<<pll_bw_hz<<"dll_bw_hz="<<dll_bw_hz<<"\r\n";
d_dump_filename =dump_filename;
// Initialize tracking ==========================================
@@ -118,6 +120,7 @@ gps_l1_ca_dll_pll_tracking_cc::gps_l1_ca_dll_pll_tracking_cc(unsigned int satell
// sample synchronization
d_sample_counter=0;
d_sample_counter_seconds=0;
d_acq_sample_stamp=0;
d_enable_tracking=false;
@@ -141,8 +144,9 @@ void gps_l1_ca_dll_pll_tracking_cc::start_tracking(){
*/
unsigned long int acq_trk_diff_samples;
float acq_trk_diff_seconds;
acq_trk_diff_samples=d_sample_counter-d_acq_sample_stamp-d_vector_length;
acq_trk_diff_seconds=acq_trk_diff_samples/(float)d_fs_in;
acq_trk_diff_samples=d_sample_counter-d_acq_sample_stamp;//-d_vector_length;
std::cout<<"acq_trk_diff_samples="<<acq_trk_diff_samples<<"\r\n";
acq_trk_diff_seconds=(float)acq_trk_diff_samples/(float)d_fs_in;
//doppler effect
// Fd=(C/(C+Vr))*F
float radial_velocity;
@@ -155,18 +159,25 @@ void gps_l1_ca_dll_pll_tracking_cc::start_tracking(){
T_chip_mod_seconds=1/d_code_freq_hz;
T_prn_mod_seconds=T_chip_mod_seconds*GPS_L1_CA_CODE_LENGTH_CHIPS;
T_prn_mod_samples=T_prn_mod_seconds*(float)d_fs_in;
d_code_phase_step_chips = d_code_freq_hz / (float)d_fs_in; //[chips]
d_next_prn_length_samples=round(T_prn_mod_samples);
//compute the code phase chips prediction
float delta_T_prn_samples;
float delay_correction_samples;
delta_T_prn_samples=fmod((float)acq_trk_diff_samples,T_prn_mod_samples);
delay_correction_samples=T_prn_mod_samples-delta_T_prn_samples;
d_acq_code_phase_samples=d_acq_code_phase_samples-delay_correction_samples;
if (d_acq_code_phase_samples<0){
d_acq_code_phase_samples=d_acq_code_phase_samples+T_prn_mod_samples;
}
float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS/GPS_L1_CA_CODE_RATE_HZ;
float T_prn_true_samples = T_prn_true_seconds*(float)d_fs_in;
float T_prn_diff_seconds;
T_prn_diff_seconds=T_prn_true_seconds-T_prn_mod_seconds;
float N_prn_diff;
N_prn_diff=acq_trk_diff_seconds/T_prn_true_seconds;
float corrected_acq_phase_samples,delay_correction_samples;
corrected_acq_phase_samples=fmod((d_acq_code_phase_samples+T_prn_diff_seconds*N_prn_diff*(float)d_fs_in),T_prn_true_samples);
if (corrected_acq_phase_samples<0)
{
corrected_acq_phase_samples=T_prn_mod_samples+corrected_acq_phase_samples;
}
delay_correction_samples=d_acq_code_phase_samples-corrected_acq_phase_samples;
d_acq_code_phase_samples=corrected_acq_phase_samples;
d_carrier_doppler_hz=d_acq_carrier_doppler_hz;
// DLL/PLL filter initialization
d_carrier_loop_filter.initialize(d_carrier_doppler_hz); //initialize the carrier filter
@@ -179,35 +190,23 @@ void gps_l1_ca_dll_pll_tracking_cc::start_tracking(){
d_carrier_lock_fail_counter=0;
d_rem_code_phase_samples=0;
d_next_rem_code_phase_samples=0;
d_rem_carr_phase_rad=0;
d_rem_code_phase_samples=0;
d_next_rem_code_phase_samples=0;
d_acc_carrier_phase_rad=0;
// ############# ENABLE DATA FILE LOG #################
if (d_dump==true)
{
if (d_dump_file.is_open()==false)
{
try {
d_dump_filename="track_ch"; //base path and name for the tracking log file
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
d_dump_filename.append(".dat");
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
std::cout<<"Tracking dump enabled on channel "<<d_channel<<" Log file: "<<d_dump_filename.c_str()<<std::endl;
}
catch (std::ifstream::failure e) {
std::cout << "channel "<<d_channel <<" Exception opening trk dump file "<<e.what()<<"\r\n";
}
}
}
d_code_phase_samples = d_acq_code_phase_samples;
// DEBUG OUTPUT
std::cout<<"Tracking start on channel "<<d_channel<<" for satellite ID* "<< this->d_satellite<< std::endl;
DLOG(INFO) << "Start tracking for satellite "<<this->d_satellite<<" received ";
// enable tracking
d_pull_in=true;
d_enable_tracking=true;
std::cout<<"PULL-IN Doppler [Hz]= "<<d_carrier_doppler_hz<<" PULL-IN Code Phase [samples]= "<<d_acq_code_phase_samples<<"\r\n";
std::cout<<"PULL-IN Doppler [Hz]= "<<d_carrier_doppler_hz<<" Code Phase correction [samples]="<<delay_correction_samples<<" PULL-IN Code Phase [samples]= "<<d_acq_code_phase_samples<<"\r\n";
}
void gps_l1_ca_dll_pll_tracking_cc::update_local_code()
@@ -235,7 +234,7 @@ void gps_l1_ca_dll_pll_tracking_cc::update_local_carrier()
{
float phase_rad, phase_step_rad;
phase_step_rad = (float)TWO_PI*d_carrier_doppler_hz/d_fs_in;
phase_step_rad = (float)TWO_PI*d_carrier_doppler_hz/(float)d_fs_in;
phase_rad=d_rem_carr_phase_rad;
for(int i = 0; i < d_current_prn_length_samples; i++) {
d_carr_sign[i] = gr_complex(cos(phase_rad),sin(phase_rad));
@@ -247,12 +246,12 @@ void gps_l1_ca_dll_pll_tracking_cc::update_local_carrier()
gps_l1_ca_dll_pll_tracking_cc::~gps_l1_ca_dll_pll_tracking_cc() {
d_dump_file.close();
delete d_ca_code;
delete d_early_code;
delete d_prompt_code;
delete d_late_code;
delete d_carr_sign;
delete d_Prompt_buffer;
delete[] d_ca_code;
delete[] d_early_code;
delete[] d_prompt_code;
delete[] d_late_code;
delete[] d_carr_sign;
delete[] d_Prompt_buffer;
}
/*! Tracking signal processing
@@ -261,33 +260,71 @@ gps_l1_ca_dll_pll_tracking_cc::~gps_l1_ca_dll_pll_tracking_cc() {
int gps_l1_ca_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) {
// if ((unsigned int)ninput_items[0]<(d_vector_length*2))
// {
// std::cout<<"End of signal detected\r\n";
// const int samples_available = ninput_items[0];
// consume_each(samples_available);
// return 0;
// }
// process vars
float carr_error;
float carr_nco;
float code_error;
float code_nco;
d_Early=gr_complex(0,0);
d_Prompt=gr_complex(0,0);
d_Late=gr_complex(0,0);
if (d_enable_tracking==true){
/*!
* Receiver signal alignment
*/
if (d_pull_in==true)
{
int samples_offset=ceil(d_acq_code_phase_samples);
consume_each(d_acq_code_phase_samples); //shift input to perform alignement with local replica
d_sample_counter+=samples_offset; //count for the processed samples
int samples_offset;
// 28/11/2011 ACQ to TRK transition BUG CORRECTION
float acq_trk_shif_correction_samples;
int acq_to_trk_delay_samples;
acq_to_trk_delay_samples=d_sample_counter-d_acq_sample_stamp;
acq_trk_shif_correction_samples=d_next_prn_length_samples-fmod((float)acq_to_trk_delay_samples,(float)d_next_prn_length_samples);
//std::cout<<"acq_trk_shif_correction="<<acq_trk_shif_correction_samples<<"\r\n";
samples_offset=round(d_acq_code_phase_samples+acq_trk_shif_correction_samples);
// /todo: Check if the sample counter sent to the next block as a time reference should be incremented AFTER sended or BEFORE
d_sample_counter_seconds = d_sample_counter_seconds + (((double)samples_offset)/(double)d_fs_in);
d_sample_counter=d_sample_counter+samples_offset; //count for the processed samples
d_pull_in=false;
//std::cout<<" samples_offset="<<samples_offset<<"\r\n";
consume_each(samples_offset); //shift input to perform alignement with local replica
return 1;
}
d_current_prn_length_samples=d_next_prn_length_samples;
float carr_error;
float carr_nco;
float code_error;
float code_nco;
const gr_complex* in = (gr_complex*) input_items[0]; //PRN start block alignement
float **out = (float **) &output_items[0];
double **out = (double **) &output_items[0];
// check for samples consistency
for(int i=0;i<d_current_prn_length_samples;i++) {
if (std::isnan(in[i].real())==true or std::isnan(in[i].imag())==true)// or std::isinf(in[i].real())==true or std::isinf(in[i].imag())==true)
{
const int samples_available= ninput_items[0];
d_sample_counter=d_sample_counter+samples_available;
LOG_AT_LEVEL(WARNING) << "Detected NaN samples at sample number "<<d_sample_counter;
consume_each(samples_available);
return 0;
}
}
// Update the prn length based on code freq (variable) and
// sampling frequency (fixed)
// variable code PRN sample block size
d_current_prn_length_samples=d_next_prn_length_samples;
update_local_code();
update_local_carrier();
gr_complex bb_signal_sample(0,0);
d_Early=gr_complex(0,0);
d_Prompt=gr_complex(0,0);
d_Late=gr_complex(0,0);
// perform Early, Prompt and Late correlation
/*!
@@ -328,8 +365,20 @@ int gps_l1_ca_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_in
T_prn_samples=T_prn_seconds*d_fs_in;
d_rem_code_phase_samples=d_next_rem_code_phase_samples;
K_blk_samples=T_prn_samples+d_rem_code_phase_samples;
d_next_prn_length_samples=round(K_blk_samples);
d_next_rem_code_phase_samples=K_blk_samples-d_next_prn_length_samples;
// Update the current PRN delay (code phase in samples)
float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS/GPS_L1_CA_CODE_RATE_HZ;
float T_prn_true_samples = T_prn_true_seconds*(float)d_fs_in;
d_code_phase_samples=d_code_phase_samples+T_prn_samples-T_prn_true_samples;
if (d_code_phase_samples<0)
{
d_code_phase_samples=T_prn_true_samples+d_code_phase_samples;
}
d_code_phase_samples=fmod(d_code_phase_samples,T_prn_true_samples);
d_next_prn_length_samples=round(K_blk_samples); //round to a discrete samples
d_next_rem_code_phase_samples=K_blk_samples-d_next_prn_length_samples; //rounding error
/*!
* \todo Improve the lock detection algorithm!
@@ -345,35 +394,72 @@ int gps_l1_ca_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_in
d_CN0_SNV_dB_Hz=gps_l1_ca_CN0_SNV(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES,d_fs_in);
d_carrier_lock_test=carrier_lock_detector(d_Prompt_buffer,CN0_ESTIMATION_SAMPLES);
// ###### TRACKING UNLOCK NOTIFICATION #####
int tracking_message;
if (d_carrier_lock_test<d_carrier_lock_threshold or d_carrier_lock_test>30)
if (d_carrier_lock_test<d_carrier_lock_threshold or d_carrier_lock_test>MINIMUM_VALID_CN0)
{
d_carrier_lock_fail_counter++;
}else{
if (d_carrier_lock_fail_counter>0) d_carrier_lock_fail_counter--;
}
if (d_carrier_lock_fail_counter>200)
if (d_carrier_lock_fail_counter>MAXIMUM_LOCK_FAIL_COUNTER)
{
std::cout<<"Channel "<<d_channel << " loss of lock!\r\n";
tracking_message=3; //loss of lock
d_channel_internal_queue->push(tracking_message);
d_carrier_lock_fail_counter=0;
d_current_prn_length_samples=(int)d_vector_length; //original dsp block length
d_enable_tracking=false; // TODO: check if disabling tracking is consistent with the channel state machine
}
//std::cout<<"d_carrier_lock_fail_counter"<<d_carrier_lock_fail_counter<<"\r\n";
}
// Output the tracking data to navigation and PVT
// Output channel 1: Prompt correlator output Q
*out[0]=d_Prompt.real();
// Output channel 2: Prompt correlator output I
*out[1]=d_Prompt.imag();
// Output channel 3: Current tracking time [ms]
*out[2]=(float)(((double)d_sample_counter/(double)d_fs_in)*1000.0);
// Output channel 4: Carrier accumulated phase
*out[3]=d_acc_carrier_phase_rad;
/*!
* \todo Output the CN0
*/
// ########### Output the tracking data to navigation and PVT ##########
// Output channel 0: Prompt correlator output Q
*out[0]=(double)d_Prompt.real();
// Output channel 1: Prompt correlator output I
*out[1]=(double)d_Prompt.imag();
// Output channel 2: PRN absolute delay [s]
*out[2]=d_sample_counter_seconds;
// Output channel 3: d_acc_carrier_phase_rad [rad]
*out[3]=(double)d_acc_carrier_phase_rad;
// Output channel 4: PRN code phase [s]
*out[4]=(double)d_code_phase_samples*(1/(float)d_fs_in);
// ########## DEBUG OUTPUT
/*!
* \todo The stop timer has to be moved to the signal source!
*/
// debug: Second counter in channel 0
if (d_channel==0)
{
if (floor(d_sample_counter/d_fs_in)!=d_last_seg)
{
d_last_seg=floor(d_sample_counter/d_fs_in);
std::cout<<"Current input signal time="<<d_last_seg<<" [s]"<<std::endl;
std::cout<<"Tracking CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<<" [dB-Hz]"<<std::endl;
//std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl;
//if (d_last_seg==5) d_carrier_lock_fail_counter=500; //DEBUG: force unlock!
}
}else
{
if (floor(d_sample_counter/d_fs_in)!=d_last_seg)
{
d_last_seg=floor(d_sample_counter/d_fs_in);
std::cout<<"Tracking CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<<" [dB-Hz]"<<std::endl;
//std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl;
}
}
}else{
double **out = (double **) &output_items[0]; //block output streams pointer
*out[0]=0;
*out[1]=0;
*out[2]=0;
*out[3]=0;
*out[4]=0;
}
if(d_dump) {
// MULTIPLEXED FILE RECORDING - Record results to file
@@ -395,8 +481,8 @@ int gps_l1_ca_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_in
d_dump_file.write((char*)&prompt_I, sizeof(float));
d_dump_file.write((char*)&prompt_Q, sizeof(float));
// PRN start sample stamp
tmp_float=(float)d_sample_counter;
d_dump_file.write((char*)&tmp_float, sizeof(float));
//tmp_float=(float)d_sample_counter;
d_dump_file.write((char*)&d_sample_counter, sizeof(unsigned long int));
// accumulated carrier phase
d_dump_file.write((char*)&d_acc_carrier_phase_rad, sizeof(float));
@@ -417,38 +503,18 @@ int gps_l1_ca_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_in
d_dump_file.write((char*)&d_carrier_lock_test, sizeof(float));
// AUX vars (for debug purposes)
tmp_float=0.0;
d_dump_file.write((char*)&tmp_float, sizeof(float));
tmp_float=0.0;
tmp_float=0;
d_dump_file.write((char*)&tmp_float, sizeof(float));
d_dump_file.write((char*)&d_sample_counter_seconds, sizeof(double));
}
catch (std::ifstream::failure e) {
std::cout << "Exception writing trk dump file "<<e.what()<<"\r\n";
}
}
// ########## DEBUG OUTPUT
// debug: Second counter in channel 0
if (d_channel==0)
{
if (floor(d_sample_counter/d_fs_in)!=d_last_seg)
{
d_last_seg=floor(d_sample_counter/d_fs_in);
std::cout<<"t="<<d_last_seg<<std::endl;
std::cout<<"TRK CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<< std::endl;
std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl;
}
}else
{
if (floor(d_sample_counter/d_fs_in)!=d_last_seg)
{
d_last_seg=floor(d_sample_counter/d_fs_in);
std::cout<<"TRK CH "<<d_channel<<" CN0="<<d_CN0_SNV_dB_Hz<< std::endl;
std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl;
}
}
}
consume_each(d_current_prn_length_samples); // this is necesary in gr_block derivates
d_sample_counter+=d_current_prn_length_samples; //count for the processed samples
d_sample_counter_seconds = d_sample_counter_seconds + (((double)d_current_prn_length_samples)/(double)d_fs_in);
d_sample_counter+=d_current_prn_length_samples; //count for the processed samples
return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false
}
@@ -470,6 +536,23 @@ void gps_l1_ca_dll_pll_tracking_cc::set_satellite(unsigned int satellite) {
void gps_l1_ca_dll_pll_tracking_cc::set_channel(unsigned int channel) {
d_channel = channel;
LOG_AT_LEVEL(INFO) << "Tracking Channel set to " << d_channel;
// ############# ENABLE DATA FILE LOG #################
if (d_dump==true)
{
if (d_dump_file.is_open()==false)
{
try {
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
d_dump_filename.append(".dat");
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
std::cout<<"Tracking dump enabled on channel "<<d_channel<<" Log file: "<<d_dump_filename.c_str()<<std::endl;
}
catch (std::ifstream::failure e) {
std::cout << "channel "<<d_channel <<" Exception opening trk dump file "<<e.what()<<"\r\n";
}
}
}
}
void gps_l1_ca_dll_pll_tracking_cc::set_acq_sample_stamp(unsigned long int sample_stamp)

View File

@@ -42,8 +42,8 @@
//#include <gnuradio/gr_sync_decimator.h>
#include "gps_sdr_signal_processing.h"
#include "tracking_2rd_DLL_filter.h"
#include "tracking_2rd_PLL_filter.h"
#include "tracking_2nd_DLL_filter.h"
#include "tracking_2nd_PLL_filter.h"
#include <queue>
#include <boost/thread/mutex.hpp>
@@ -60,6 +60,7 @@ gps_l1_ca_dll_pll_make_tracking_cc(unsigned int satellite, long if_freq,
int vector_length,
gr_msg_queue_sptr queue,
bool dump,
std::string dump_filename,
float pll_bw_hz,
float dll_bw_hz,
float early_late_space_chips);
@@ -76,6 +77,7 @@ private:
int vector_length,
gr_msg_queue_sptr queue,
bool dump,
std::string dump_filename,
float pll_bw_hz,
float dll_bw_hz,
float early_late_space_chips);
@@ -85,6 +87,7 @@ private:
int vector_length,
gr_msg_queue_sptr queue,
bool dump,
std::string dump_filename,
float pll_bw_hz,
float dll_bw_hz,
float early_late_space_chips);
@@ -123,8 +126,8 @@ private:
float d_rem_carr_phase_rad;
// PLL and DLL filter library
tracking_2rd_DLL_filter d_code_loop_filter;
tracking_2rd_PLL_filter d_carrier_loop_filter;
tracking_2nd_DLL_filter d_code_loop_filter;
tracking_2nd_PLL_filter d_carrier_loop_filter;
// acquisition
float d_acq_code_phase_samples;
@@ -134,10 +137,12 @@ private:
float d_code_freq_hz;
float d_carrier_doppler_hz;
float d_acc_carrier_phase_rad;
float d_code_phase_samples;
//PRN period in samples
int d_current_prn_length_samples;
int d_next_prn_length_samples;
double d_sample_counter_seconds;
//processing samples counters
unsigned long int d_sample_counter;

View File

@@ -3,5 +3,5 @@ project : build-dir ../../../../build ;
obj tracking_discriminators : tracking_discriminators.cc ;
obj CN_estimators : CN_estimators.cc ;
obj tracking_FLL_PLL_filter : tracking_FLL_PLL_filter.cc ;
obj tracking_2rd_PLL_filter : tracking_2rd_PLL_filter.cc ;
obj tracking_2rd_DLL_filter : tracking_2rd_DLL_filter.cc ;
obj tracking_2nd_PLL_filter : tracking_2nd_PLL_filter.cc ;
obj tracking_2nd_DLL_filter : tracking_2nd_DLL_filter.cc ;

View File

@@ -1,5 +1,5 @@
/*!
* \file tracking_2rd_DLL_filter.cc
* \file tracking_2nd_DLL_filter.cc
* \brief Class that implements 2 order DLL filter for code tracking loop.
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
@@ -34,10 +34,10 @@
*/
#include "tracking_2rd_DLL_filter.h"
#include "tracking_2nd_DLL_filter.h"
void tracking_2rd_DLL_filter::calculate_lopp_coef(float* tau1,float* tau2, float lbw, float zeta, float k){
void tracking_2nd_DLL_filter::calculate_lopp_coef(float* tau1,float* tau2, float lbw, float zeta, float k){
// Solve natural frequency
float Wn;
Wn = lbw*8*zeta / (4*zeta*zeta + 1);
@@ -46,13 +46,13 @@ void tracking_2rd_DLL_filter::calculate_lopp_coef(float* tau1,float* tau2, float
*tau2 = (2.0 * zeta) / Wn;
}
void tracking_2rd_DLL_filter::set_DLL_BW(float dll_bw_hz)
void tracking_2nd_DLL_filter::set_DLL_BW(float dll_bw_hz)
{
//Calculate filter coefficient values
d_dllnoisebandwidth=dll_bw_hz;
calculate_lopp_coef(&d_tau1_code, &d_tau2_code, d_dllnoisebandwidth, d_dlldampingratio,1.0);// Calculate filter coefficient values
}
void tracking_2rd_DLL_filter::initialize(float d_acq_code_phase_samples)
void tracking_2nd_DLL_filter::initialize(float d_acq_code_phase_samples)
{
// code tracking loop parameters
d_old_code_nco = 0.0;
@@ -60,7 +60,7 @@ void tracking_2rd_DLL_filter::initialize(float d_acq_code_phase_samples)
}
float tracking_2rd_DLL_filter::get_code_nco(float DLL_discriminator)
float tracking_2nd_DLL_filter::get_code_nco(float DLL_discriminator)
{
float code_nco;
code_nco = d_old_code_nco + (d_tau2_code/d_tau1_code)*(DLL_discriminator - d_old_code_error) + DLL_discriminator * (d_pdi_code/d_tau1_code);
@@ -69,13 +69,13 @@ float tracking_2rd_DLL_filter::get_code_nco(float DLL_discriminator)
return code_nco;
}
tracking_2rd_DLL_filter::tracking_2rd_DLL_filter ()
tracking_2nd_DLL_filter::tracking_2nd_DLL_filter ()
{
d_pdi_code = 0.001;// Summation interval for code
d_dlldampingratio=0.7;
}
tracking_2rd_DLL_filter::~tracking_2rd_DLL_filter ()
tracking_2nd_DLL_filter::~tracking_2nd_DLL_filter ()
{
}

View File

@@ -1,5 +1,5 @@
/*!
* \file tracking_2rd_DLL_filter.h
* \file tracking_2nd_DLL_filter.h
* \brief Class that implements 2 order DLL filter for code tracking loop.
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
@@ -33,10 +33,10 @@
* -------------------------------------------------------------------------
*/
#ifndef TRACKING_2RD_DLL_FILTER_H_
#define TRACKING_2RD_DLL_FILTER_H_
#ifndef TRACKING_2ND_DLL_FILTER_H_
#define TRACKING_2ND_DLL_FILTER_H_
class tracking_2rd_DLL_filter
class tracking_2nd_DLL_filter
{
private:
// PLL filter parameters
@@ -54,8 +54,8 @@ public:
void set_DLL_BW(float dll_bw_hz);
void initialize(float d_acq_code_phase_samples);
float get_code_nco(float DLL_discriminator);
tracking_2rd_DLL_filter();
~tracking_2rd_DLL_filter();
tracking_2nd_DLL_filter();
~tracking_2nd_DLL_filter();
};
#endif

View File

@@ -1,5 +1,5 @@
/*!
* \file tracking_2rd_PLL_filter.cc
* \file tracking_2nd_PLL_filter.cc
* \brief Class that implements 2 order PLL filter for tracking carrier loop.
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
@@ -33,10 +33,10 @@
* -------------------------------------------------------------------------
*/
#include "tracking_2rd_PLL_filter.h"
#include "tracking_2nd_PLL_filter.h"
void tracking_2rd_PLL_filter::calculate_lopp_coef(float* tau1,float* tau2, float lbw, float zeta, float k){
void tracking_2nd_PLL_filter::calculate_lopp_coef(float* tau1,float* tau2, float lbw, float zeta, float k){
// Solve natural frequency
float Wn;
Wn = lbw*8*zeta / (4*zeta*zeta + 1);
@@ -45,20 +45,20 @@ void tracking_2rd_PLL_filter::calculate_lopp_coef(float* tau1,float* tau2, float
*tau2 = (2.0 * zeta) / Wn;
}
void tracking_2rd_PLL_filter::set_PLL_BW(float pll_bw_hz)
void tracking_2nd_PLL_filter::set_PLL_BW(float pll_bw_hz)
{
//Calculate filter coefficient values
d_pllnoisebandwidth=pll_bw_hz;
calculate_lopp_coef(&d_tau1_carr, &d_tau2_carr, d_pllnoisebandwidth, d_plldampingratio,0.25);// Calculate filter coefficient values
}
void tracking_2rd_PLL_filter::initialize(float d_acq_carrier_doppler_hz)
void tracking_2nd_PLL_filter::initialize(float d_acq_carrier_doppler_hz)
{
// carrier/Costas loop parameters
d_old_carr_nco = 0.0;
d_old_carr_error = 0.0;
}
float tracking_2rd_PLL_filter::get_carrier_nco(float PLL_discriminator)
float tracking_2nd_PLL_filter::get_carrier_nco(float PLL_discriminator)
{
float carr_nco;
carr_nco = d_old_carr_nco+(d_tau2_carr/d_tau1_carr)*(PLL_discriminator - d_old_carr_error) + PLL_discriminator * (d_pdi_carr/d_tau1_carr);
@@ -67,14 +67,14 @@ float tracking_2rd_PLL_filter::get_carrier_nco(float PLL_discriminator)
return carr_nco;
}
tracking_2rd_PLL_filter::tracking_2rd_PLL_filter ()
tracking_2nd_PLL_filter::tracking_2nd_PLL_filter ()
{
//--- PLL variables --------------------------------------------------------
d_pdi_carr = 0.001;// Summation interval for carrier
d_plldampingratio=0.65;
}
tracking_2rd_PLL_filter::~tracking_2rd_PLL_filter ()
tracking_2nd_PLL_filter::~tracking_2nd_PLL_filter ()
{
}

View File

@@ -1,5 +1,5 @@
/*!
* \file tracking_2rd_PLL_filter.h
* \file tracking_2nd_PLL_filter.h
* \brief Class that implements 2 order PLL filter for tracking carrier loop
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
@@ -33,10 +33,10 @@
* -------------------------------------------------------------------------
*/
#ifndef TRACKING_2RD_PLL_FILTER_H_
#define TRACKING_2RD_PLL_FILTER_H_
#ifndef TRACKING_2ND_PLL_FILTER_H_
#define TRACKING_2ND_PLL_FILTER_H_
class tracking_2rd_PLL_filter
class tracking_2nd_PLL_filter
{
private:
// PLL filter parameters
@@ -55,8 +55,8 @@ public:
void set_PLL_BW(float pll_bw_hz);
void initialize(float d_acq_carrier_doppler_hz);
float get_carrier_nco(float PLL_discriminator);
tracking_2rd_PLL_filter();
~tracking_2rd_PLL_filter();
tracking_2nd_PLL_filter();
~tracking_2nd_PLL_filter();
};
#endif

View File

@@ -76,7 +76,6 @@ void tracking_FLL_PLL_filter::initialize(float d_acq_carrier_doppler_hz)
d_pll_w = d_acq_carrier_doppler_hz;
d_pll_x = 0;
}
std::cout<<" d_pll_x init = "<<d_pll_x<<"\r\n";
}
float tracking_FLL_PLL_filter::get_carrier_error(float FLL_discriminator, float PLL_discriminator, float correlation_time_s)