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:
103
src/algorithms/PVT/adapters/gps_l1_ca_pvt.cc
Normal file
103
src/algorithms/PVT/adapters/gps_l1_ca_pvt.cc
Normal 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_;
|
||||
}
|
||||
|
||||
94
src/algorithms/PVT/adapters/gps_l1_ca_pvt.h
Normal file
94
src/algorithms/PVT/adapters/gps_l1_ca_pvt.h
Normal 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
|
||||
3
src/algorithms/PVT/adapters/jamfile.jam
Normal file
3
src/algorithms/PVT/adapters/jamfile.jam
Normal file
@@ -0,0 +1,3 @@
|
||||
project : build-dir ../../../../build ;
|
||||
|
||||
obj gps_l1_ca_pvt : gps_l1_ca_pvt.cc ;
|
||||
167
src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.cc
Normal file
167
src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
101
src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.h
Normal file
101
src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.h
Normal 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
|
||||
3
src/algorithms/PVT/gnuradio_blocks/jamfile.jam
Normal file
3
src/algorithms/PVT/gnuradio_blocks/jamfile.jam
Normal file
@@ -0,0 +1,3 @@
|
||||
project : build-dir ../../../../build ;
|
||||
|
||||
obj gps_l1_ca_pvt_cc : gps_l1_ca_pvt_cc.cc ;
|
||||
3
src/algorithms/PVT/jamfile.jam
Normal file
3
src/algorithms/PVT/jamfile.jam
Normal file
@@ -0,0 +1,3 @@
|
||||
build-project adapters ;
|
||||
build-project gnuradio_blocks ;
|
||||
build-project libs ;
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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 ;
|
||||
126
src/algorithms/PVT/libs/kml_printer.cc
Normal file
126
src/algorithms/PVT/libs/kml_printer.cc
Normal 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 ()
|
||||
{
|
||||
}
|
||||
59
src/algorithms/PVT/libs/kml_printer.h
Normal file
59
src/algorithms/PVT/libs/kml_printer.h
Normal 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
|
||||
@@ -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_);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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 ;
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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() << ")";
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
build-project adapters ;
|
||||
build-project gnuradio_blocks ;
|
||||
build-project libs ;
|
||||
build-project gnuradio_blocks ;
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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() << ")";
|
||||
|
||||
|
||||
@@ -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_;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ;
|
||||
@@ -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 ()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 ()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user