mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-11-27 12:25:17 +00:00
E5a signal generator and minor bug fixes.
This commit is contained in:
@@ -29,11 +29,13 @@
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "signal_generator.h"
|
||||
#include <glog/logging.h>
|
||||
#include "configuration_interface.h"
|
||||
#include "Galileo_E1.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "Galileo_E5a.h"
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
@@ -46,6 +48,7 @@ SignalGenerator::SignalGenerator(ConfigurationInterface* configuration,
|
||||
std::string default_item_type = "gr_complex";
|
||||
std::string default_dump_file = "./data/gen_source.dat";
|
||||
std::string default_system = "G";
|
||||
std::string default_signal = "1C";
|
||||
|
||||
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
@@ -57,6 +60,7 @@ SignalGenerator::SignalGenerator(ConfigurationInterface* configuration,
|
||||
float BW_BB = configuration->property("SignalSource.BW_BB", 1.0);
|
||||
unsigned int num_satellites = configuration->property("SignalSource.num_satellites", 1);
|
||||
|
||||
std::vector<std::string> signal1;
|
||||
std::vector<std::string> system;
|
||||
std::vector<unsigned int> PRN;
|
||||
std::vector<float> CN0_dB;
|
||||
@@ -66,6 +70,7 @@ SignalGenerator::SignalGenerator(ConfigurationInterface* configuration,
|
||||
for (unsigned int sat_idx = 0; sat_idx < num_satellites; sat_idx++)
|
||||
{
|
||||
std::string sat = std::to_string(sat_idx);
|
||||
signal1.push_back(configuration->property("SignalSource.signal_" + sat, default_signal));
|
||||
system.push_back(configuration->property("SignalSource.system_" + sat, default_system));
|
||||
PRN.push_back(configuration->property("SignalSource.PRN_" + sat, 1));
|
||||
CN0_dB.push_back(configuration->property("SignalSource.CN0_dB_" + sat, 10));
|
||||
@@ -73,14 +78,25 @@ SignalGenerator::SignalGenerator(ConfigurationInterface* configuration,
|
||||
delay_chips.push_back(configuration->property("SignalSource.delay_chips_" + sat, 0));
|
||||
}
|
||||
|
||||
// If Galileo signal is present -> vector duration = 100 ms (25 * 4 ms)
|
||||
// If Galileo signal is present -> vector duration = 100 ms (25 * 4 ms)
|
||||
// If there is only GPS signal (Galileo signal not present) -> vector duration = 1 ms
|
||||
unsigned int vector_length = 0;
|
||||
if (std::find(system.begin(), system.end(), "E") != system.end())
|
||||
{
|
||||
vector_length = round((float)fs_in / (Galileo_E1_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E1_B_CODE_LENGTH_CHIPS))
|
||||
* Galileo_E1_C_SECONDARY_CODE_LENGTH;
|
||||
if (signal1[0].at(0)=='5')
|
||||
{
|
||||
vector_length = round((float) fs_in / (Galileo_E5a_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E5a_CODE_LENGTH_CHIPS));
|
||||
// vector_length = round((float) fs_in / (Galileo_E5a_CODE_CHIP_RATE_HZ
|
||||
// / Galileo_E5a_CODE_LENGTH_CHIPS))
|
||||
// * Galileo_E5a_Q_SECONDARY_CODE_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
vector_length = round((float)fs_in / (Galileo_E1_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E1_B_CODE_LENGTH_CHIPS))
|
||||
* Galileo_E1_C_SECONDARY_CODE_LENGTH;
|
||||
}
|
||||
}
|
||||
else if (std::find(system.begin(), system.end(), "G") != system.end())
|
||||
{
|
||||
@@ -92,7 +108,7 @@ SignalGenerator::SignalGenerator(ConfigurationInterface* configuration,
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
DLOG(INFO) << "Item size " << item_size_;
|
||||
gen_source_ = signal_make_generator_c(system, PRN, CN0_dB, doppler_Hz, delay_chips,
|
||||
gen_source_ = signal_make_generator_c(signal1, system, PRN, CN0_dB, doppler_Hz, delay_chips,
|
||||
data_flag, noise_flag, fs_in, vector_length, BW_BB);
|
||||
|
||||
vector_to_stream_ = gr::blocks::vector_to_stream::make(item_size_, vector_length);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#ifndef GNSS_SDR_SIGNAL_GENERATOR_H_
|
||||
#define GNSS_SDR_SIGNAL_GENERATOR_H_
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
@@ -45,9 +46,9 @@
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class generates synthesized GNSS signal.
|
||||
*
|
||||
*/
|
||||
* \brief This class generates synthesized GNSS signal.
|
||||
*
|
||||
*/
|
||||
class SignalGenerator: public GNSSBlockInterface
|
||||
{
|
||||
public:
|
||||
@@ -62,8 +63,8 @@ public:
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "GNSSSignalGenerator".
|
||||
*/
|
||||
* \brief Returns "GNSSSignalGenerator".
|
||||
*/
|
||||
std::string implementation()
|
||||
{
|
||||
return "GNSSSignalGenerator";
|
||||
@@ -91,5 +92,4 @@ private:
|
||||
gr::blocks::file_sink::sptr file_sink_;
|
||||
boost::shared_ptr<gr::msg_queue> queue_;
|
||||
};
|
||||
|
||||
#endif /*GNSS_SDR_SIGNAL_GENERATOR_H_*/
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
/*!
|
||||
* \file signal_generator_c.cc
|
||||
* \brief GNU Radio source block that generates synthesized GNSS signal.
|
||||
* \author Marc Molina, 2013. marc.molina.pena@gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
* \file signal_generator_c.cc
|
||||
* \brief GNU Radio source block that generates synthesized GNSS signal.
|
||||
* \author Marc Molina, 2013. marc.molina.pena@gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <gnuradio/io_signature.h>
|
||||
#include <volk/volk.h>
|
||||
@@ -34,32 +34,35 @@
|
||||
#include "gps_sdr_signal_processing.h"
|
||||
#include "galileo_e1_signal_processing.h"
|
||||
#include "nco_lib.h"
|
||||
|
||||
|
||||
#include "galileo_e5_signal_processing.h"
|
||||
#include "Galileo_E5a.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
/*
|
||||
* Create a new instance of signal_generator_c and return
|
||||
* a boost shared_ptr. This is effectively the public constructor.
|
||||
*/
|
||||
* Create a new instance of signal_generator_c and return
|
||||
* a boost shared_ptr. This is effectively the public constructor.
|
||||
*/
|
||||
signal_generator_c_sptr
|
||||
signal_make_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
signal_make_generator_c (std::vector<std::string> signal1, std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(new signal_generator_c(system, PRN, CN0_dB, doppler_Hz, delay_chips,
|
||||
return gnuradio::get_initial_sptr(new signal_generator_c(signal1, system, PRN, CN0_dB, doppler_Hz, delay_chips,
|
||||
data_flag, noise_flag, fs_in, vector_length, BW_BB));
|
||||
}
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
signal_generator_c::signal_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
* The private constructor
|
||||
*/
|
||||
signal_generator_c::signal_generator_c (std::vector<std::string> signal1, std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB) :
|
||||
|
||||
gr::block ("signal_gen_cc", gr::io_signature::make(0, 0, sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)*vector_length)),
|
||||
signal_(signal1),
|
||||
system_(system),
|
||||
PRN_(PRN),
|
||||
CN0_dB_(CN0_dB),
|
||||
@@ -78,6 +81,9 @@ signal_generator_c::signal_generator_c (std::vector<std::string> system, const s
|
||||
|
||||
void signal_generator_c::init()
|
||||
{
|
||||
work_counter_ = 0;
|
||||
std::cout << "work counter reset to 0"<< std::endl;
|
||||
|
||||
if (posix_memalign((void**)&complex_phase_, 16, vector_length_ * sizeof(gr_complex)) == 0){};
|
||||
|
||||
// True if Galileo satellites are present
|
||||
@@ -86,8 +92,12 @@ void signal_generator_c::init()
|
||||
for (unsigned int sat = 0; sat < num_sats_; sat++)
|
||||
{
|
||||
start_phase_rad_.push_back(0);
|
||||
current_data_bit_int_.push_back(1);
|
||||
current_data_bits_.push_back(gr_complex(1, 0));
|
||||
ms_counter_.push_back(0);
|
||||
data_modulation_.push_back((Galileo_E5a_I_SECONDARY_CODE.at(0)=='0' ? 1 : -1));
|
||||
pilot_modulation_.push_back((Galileo_E5a_Q_SECONDARY_CODE[PRN_[sat]].at(0)=='0' ? 1 : -1));
|
||||
|
||||
|
||||
if (system_[sat] == "G")
|
||||
{
|
||||
@@ -99,35 +109,50 @@ void signal_generator_c::init()
|
||||
}
|
||||
else if (system_[sat] == "E")
|
||||
{
|
||||
samples_per_code_.push_back(round((float)fs_in_ / (Galileo_E1_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E1_B_CODE_LENGTH_CHIPS)));
|
||||
if (signal_[sat].at(0)=='5')
|
||||
{
|
||||
// int codelen = (int)(Galileo_E5a_CODE_LENGTH_CHIPS * Galileo_E5a_Q_SECONDARY_CODE_LENGTH);
|
||||
|
||||
num_of_codes_per_vector_.push_back((int)Galileo_E1_C_SECONDARY_CODE_LENGTH);
|
||||
data_bit_duration_ms_.push_back(1e3/Galileo_E1_B_SYMBOL_RATE_BPS);
|
||||
int codelen = (int)Galileo_E5a_CODE_LENGTH_CHIPS;
|
||||
samples_per_code_.push_back(round((float)fs_in_ / (Galileo_E5a_CODE_CHIP_RATE_HZ
|
||||
/ codelen)));
|
||||
num_of_codes_per_vector_.push_back(1);
|
||||
|
||||
// num_of_codes_per_vector_.push_back((int)Galileo_E5a_Q_SECONDARY_CODE_LENGTH);
|
||||
data_bit_duration_ms_.push_back(1e3/Galileo_E5a_SYMBOL_RATE_BPS);
|
||||
}
|
||||
else
|
||||
{
|
||||
samples_per_code_.push_back(round((float)fs_in_ / (Galileo_E1_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E1_B_CODE_LENGTH_CHIPS)));
|
||||
|
||||
num_of_codes_per_vector_.push_back((int)Galileo_E1_C_SECONDARY_CODE_LENGTH);
|
||||
data_bit_duration_ms_.push_back(1e3/Galileo_E1_B_SYMBOL_RATE_BPS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
random_ = new gr::random();
|
||||
|
||||
// std::cout << "fs_in: " << fs_in_ << std::endl;
|
||||
// std::cout << "data_flag: " << data_flag_ << std::endl;
|
||||
// std::cout << "noise_flag_: " << noise_flag_ << std::endl;
|
||||
// std::cout << "num_sats_: " << num_sats_ << std::endl;
|
||||
// std::cout << "vector_length_: " << vector_length_ << std::endl;
|
||||
// std::cout << "BW_BB_: " << BW_BB_ << std::endl;
|
||||
std::cout << "fs_in: " << fs_in_ << std::endl;
|
||||
std::cout << "data_flag: " << data_flag_ << std::endl;
|
||||
std::cout << "noise_flag_: " << noise_flag_ << std::endl;
|
||||
std::cout << "num_sats_: " << num_sats_ << std::endl;
|
||||
std::cout << "vector_length_: " << vector_length_ << std::endl;
|
||||
std::cout << "BW_BB_: " << BW_BB_ << std::endl;
|
||||
|
||||
// for (unsigned int i = 0; i < num_sats_; i++)
|
||||
// {
|
||||
// std::cout << "Sat " << i << ": " << std::endl;
|
||||
// std::cout << " System " << system_[i] << ": " << std::endl;
|
||||
// std::cout << " PRN: " << PRN_[i] << std::endl;
|
||||
// std::cout << " CN0: " << CN0_dB_[i] << std::endl;
|
||||
// std::cout << " Doppler: " << doppler_Hz_[i] << std::endl;
|
||||
// std::cout << " Delay: " << delay_chips_[i] << std::endl;
|
||||
// std::cout << " Samples per code = " << samples_per_code_[i] << std::endl;
|
||||
// std::cout << " codes per vector = " << num_of_codes_per_vector_[i] << std::endl;
|
||||
// std::cout << " data_bit_duration = " << data_bit_duration_ms_[i] << std::endl;
|
||||
// }
|
||||
for (unsigned int i = 0; i < num_sats_; i++)
|
||||
{
|
||||
std::cout << "Sat " << i << ": " << std::endl;
|
||||
std::cout << " System " << system_[i] << ": " << std::endl;
|
||||
std::cout << " PRN: " << PRN_[i] << std::endl;
|
||||
std::cout << " CN0: " << CN0_dB_[i] << std::endl;
|
||||
std::cout << " Doppler: " << doppler_Hz_[i] << std::endl;
|
||||
std::cout << " Delay: " << delay_chips_[i] << std::endl;
|
||||
std::cout << " Samples per code = " << samples_per_code_[i] << std::endl;
|
||||
std::cout << " codes per vector = " << num_of_codes_per_vector_[i] << std::endl;
|
||||
std::cout << " data_bit_duration = " << data_bit_duration_ms_[i] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void signal_generator_c::generate_codes()
|
||||
@@ -141,6 +166,7 @@ void signal_generator_c::generate_codes()
|
||||
vector_length_ * sizeof(gr_complex)) == 0){};
|
||||
|
||||
gr_complex code[64000];//[samples_per_code_[sat]];
|
||||
//gr_complex code[64000];
|
||||
|
||||
if (system_[sat] == "G")
|
||||
{
|
||||
@@ -166,61 +192,111 @@ void signal_generator_c::generate_codes()
|
||||
}
|
||||
else if (system_[sat] == "E")
|
||||
{
|
||||
// Generate one code-period of E1B signal
|
||||
bool cboc = true;
|
||||
char signal[3];
|
||||
strcpy(signal, "1B");
|
||||
if(signal_[sat].at(0)=='5')
|
||||
{
|
||||
char signal[3];
|
||||
// strcpy(signal,"5I");
|
||||
strcpy(signal,"5X");
|
||||
|
||||
galileo_e1_code_gen_complex_sampled(code, signal, cboc, PRN_[sat], fs_in_,
|
||||
(int)Galileo_E1_B_CODE_LENGTH_CHIPS - delay_chips_[sat]);
|
||||
if (posix_memalign((void**)&(sampled_code_data_[sat]), 16,
|
||||
vector_length_ * sizeof(gr_complex)) == 0){};
|
||||
|
||||
// Obtain the desired CN0 assuming that Pn = 1.
|
||||
if (noise_flag_)
|
||||
{
|
||||
for (unsigned int i = 0; i < samples_per_code_[sat]; i++)
|
||||
{
|
||||
code[i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
|
||||
}
|
||||
}
|
||||
// galileo_e5_a_code_gen_complex_sampled(sampled_code_data_[sat] , signal, PRN_[sat], fs_in_,
|
||||
// (int)Galileo_E5a_Q_SECONDARY_CODE_LENGTH - delay_chips_[sat], true);
|
||||
|
||||
// Concatenate "num_of_codes_per_vector_" codes
|
||||
for (unsigned int i = 0; i < num_of_codes_per_vector_[sat]; i++)
|
||||
{
|
||||
memcpy(&(sampled_code_data_[sat][i*samples_per_code_[sat]]),
|
||||
code, sizeof(gr_complex)*samples_per_code_[sat]);
|
||||
}
|
||||
galileo_e5_a_code_gen_complex_sampled(sampled_code_data_[sat] , signal, PRN_[sat], fs_in_,
|
||||
(int)Galileo_E5a_CODE_LENGTH_CHIPS - delay_chips_[sat],false);
|
||||
|
||||
// Generate E1C signal (25 code-periods, with secondary code)
|
||||
if (posix_memalign((void**)&(sampled_code_pilot_[sat]), 16,
|
||||
vector_length_ * sizeof(gr_complex)) == 0){};
|
||||
//// std::ofstream myfile;
|
||||
// //myfile.open ("example_sink_gencode.dat");
|
||||
// std::ofstream myfile("example_sink_gencode.bin",std::ios_base::binary);
|
||||
//// for (int k=0; k< vector_length_; k++)
|
||||
//// {
|
||||
// myfile.write((char*)&sampled_code_data_[sat],sizeof(gr_complex)*vector_length_);
|
||||
// //myfile << sampled_code_data_[sat][k];
|
||||
//// }
|
||||
//
|
||||
// myfile.close();
|
||||
|
||||
strcpy(signal, "1C");
|
||||
//std::cout << "checking tiered code" << sampled_code_data_[sat][0] << sampled_code_data_[sat][1] << sampled_code_data_[sat][2] << sampled_code_data_[sat][3] << sampled_code_data_[sat][4] << sampled_code_data_[sat][1200000] << sampled_code_data_[sat][1200000-1] << std::endl;
|
||||
|
||||
galileo_e1_code_gen_complex_sampled(sampled_code_pilot_[sat], signal, cboc, PRN_[sat], fs_in_,
|
||||
(int)Galileo_E1_B_CODE_LENGTH_CHIPS-delay_chips_[sat], true);
|
||||
// PILOT
|
||||
// if (posix_memalign((void**)&(sampled_code_pilot_[sat]), 16,
|
||||
// vector_length_ * sizeof(gr_complex)) == 0){};
|
||||
//
|
||||
// strcpy(signal, "5Q");
|
||||
//
|
||||
// galileo_e5_a_code_gen_complex_sampled(sampled_code_pilot_[sat] , signal, PRN_[sat], fs_in_,
|
||||
// (int)Galileo_E5a_CODE_LENGTH_CHIPS - delay_chips_[sat], false);
|
||||
//noise
|
||||
if (noise_flag_)
|
||||
{
|
||||
for (unsigned int i = 0; i < vector_length_; i++)
|
||||
{
|
||||
sampled_code_data_[sat][i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
|
||||
//sampled_code_pilot_[sat][i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Obtain the desired CN0 assuming that Pn = 1.
|
||||
if (noise_flag_)
|
||||
{
|
||||
for (unsigned int i = 0; i < vector_length_; i++)
|
||||
{
|
||||
sampled_code_pilot_[sat][i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Generate one code-period of E1B signal
|
||||
bool cboc = true;
|
||||
char signal[3];
|
||||
strcpy(signal, "1B");
|
||||
|
||||
galileo_e1_code_gen_complex_sampled(code, signal, cboc, PRN_[sat], fs_in_,
|
||||
(int)Galileo_E1_B_CODE_LENGTH_CHIPS - delay_chips_[sat]);
|
||||
|
||||
// Obtain the desired CN0 assuming that Pn = 1.
|
||||
if (noise_flag_)
|
||||
{
|
||||
for (unsigned int i = 0; i < samples_per_code_[sat]; i++)
|
||||
{
|
||||
code[i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Concatenate "num_of_codes_per_vector_" codes
|
||||
for (unsigned int i = 0; i < num_of_codes_per_vector_[sat]; i++)
|
||||
{
|
||||
memcpy(&(sampled_code_data_[sat][i*samples_per_code_[sat]]),
|
||||
code, sizeof(gr_complex)*samples_per_code_[sat]);
|
||||
}
|
||||
|
||||
// Generate E1C signal (25 code-periods, with secondary code)
|
||||
if (posix_memalign((void**)&(sampled_code_pilot_[sat]), 16,
|
||||
vector_length_ * sizeof(gr_complex)) == 0){};
|
||||
|
||||
strcpy(signal, "1C");
|
||||
|
||||
galileo_e1_code_gen_complex_sampled(sampled_code_pilot_[sat], signal, cboc, PRN_[sat], fs_in_,
|
||||
(int)Galileo_E1_B_CODE_LENGTH_CHIPS-delay_chips_[sat], true);
|
||||
|
||||
// Obtain the desired CN0 assuming that Pn = 1.
|
||||
if (noise_flag_)
|
||||
{
|
||||
for (unsigned int i = 0; i < vector_length_; i++)
|
||||
{
|
||||
sampled_code_pilot_[sat][i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
signal_generator_c::~signal_generator_c()
|
||||
{
|
||||
for (unsigned int sat = 0; sat < num_sats_; sat++)
|
||||
{
|
||||
free(sampled_code_data_[sat]);
|
||||
if (system_[sat] == "E")
|
||||
if (system_[sat] == "E" && signal_[sat].at(0)!='5')
|
||||
{
|
||||
free(sampled_code_pilot_[sat]);
|
||||
}
|
||||
@@ -232,11 +308,14 @@ signal_generator_c::~signal_generator_c()
|
||||
|
||||
int signal_generator_c::general_work (int noutput_items,
|
||||
gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
gr_complex *out = (gr_complex *) output_items[0];
|
||||
|
||||
work_counter_++;
|
||||
std::cout<<"work counter = "<<work_counter_<<std::endl;
|
||||
|
||||
unsigned int out_idx = 0;
|
||||
unsigned int i = 0;
|
||||
unsigned int k = 0;
|
||||
@@ -290,36 +369,73 @@ int signal_generator_c::general_work (int noutput_items,
|
||||
|
||||
else if (system_[sat] == "E")
|
||||
{
|
||||
unsigned int delay_samples = (delay_chips_[sat] % (int)Galileo_E1_B_CODE_LENGTH_CHIPS)
|
||||
* samples_per_code_[sat] / Galileo_E1_B_CODE_LENGTH_CHIPS;
|
||||
if(signal_[sat].at(0)=='5')
|
||||
{
|
||||
// EACH WORK outputs 1 modulated primary code
|
||||
//int codelen = (int)(Galileo_E5a_CODE_LENGTH_CHIPS * Galileo_E5a_Q_SECONDARY_CODE_LENGTH);
|
||||
int codelen = (int)Galileo_E5a_CODE_LENGTH_CHIPS;
|
||||
unsigned int delay_samples = (delay_chips_[sat] % codelen)
|
||||
* samples_per_code_[sat] / codelen;
|
||||
for (k = 0; k < delay_samples; k++)
|
||||
{
|
||||
out[out_idx] += (gr_complex(sampled_code_data_[sat][out_idx].real()*data_modulation_[sat] ,
|
||||
sampled_code_data_[sat][out_idx].imag()*pilot_modulation_[sat]) )
|
||||
* complex_phase_[out_idx];
|
||||
out_idx++;
|
||||
}
|
||||
if (ms_counter_[sat]%data_bit_duration_ms_[sat] == 0 && data_flag_)
|
||||
{
|
||||
// New random data bit
|
||||
current_data_bit_int_[sat] = (rand()%2) == 0 ? 1 : -1;
|
||||
data_modulation_[sat] = current_data_bit_int_[sat] * (Galileo_E5a_I_SECONDARY_CODE.at(ms_counter_[sat]%20)=='0' ? 1 : -1);
|
||||
pilot_modulation_[sat] = (Galileo_E5a_Q_SECONDARY_CODE[PRN_[sat]].at(ms_counter_[sat]%100)=='0' ? 1 : -1);
|
||||
}
|
||||
for (k = delay_samples; k < samples_per_code_[sat]; k++)
|
||||
{
|
||||
out[out_idx] += (gr_complex(sampled_code_data_[sat][out_idx].real()*data_modulation_[sat] ,
|
||||
sampled_code_data_[sat][out_idx].imag()*pilot_modulation_[sat]) )
|
||||
* complex_phase_[out_idx];
|
||||
out_idx++;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_of_codes_per_vector_[sat]; i++)
|
||||
{
|
||||
for (k = 0; k < delay_samples; k++)
|
||||
{
|
||||
out[out_idx] += (sampled_code_data_[sat][out_idx] * current_data_bits_[sat]
|
||||
- sampled_code_pilot_[sat][out_idx])
|
||||
* complex_phase_[out_idx];
|
||||
out_idx++;
|
||||
}
|
||||
ms_counter_[sat] = ms_counter_[sat] + (int)round(1e3*GALILEO_E5a_CODE_PERIOD);
|
||||
|
||||
if (ms_counter_[sat] == 0 && data_flag_)
|
||||
{
|
||||
// New random data bit
|
||||
current_data_bits_[sat] = gr_complex((rand()%2) == 0 ? 1 : -1, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int delay_samples = (delay_chips_[sat] % (int)Galileo_E1_B_CODE_LENGTH_CHIPS)
|
||||
* samples_per_code_[sat] / Galileo_E1_B_CODE_LENGTH_CHIPS;
|
||||
|
||||
for (k = delay_samples; k < samples_per_code_[sat]; k++)
|
||||
{
|
||||
out[out_idx] += (sampled_code_data_[sat][out_idx] * current_data_bits_[sat]
|
||||
- sampled_code_pilot_[sat][out_idx])
|
||||
* complex_phase_[out_idx];
|
||||
out_idx++;
|
||||
}
|
||||
for (i = 0; i < num_of_codes_per_vector_[sat]; i++)
|
||||
{
|
||||
for (k = 0; k < delay_samples; k++)
|
||||
{
|
||||
out[out_idx] += (sampled_code_data_[sat][out_idx] * current_data_bits_[sat]
|
||||
- sampled_code_pilot_[sat][out_idx])
|
||||
* complex_phase_[out_idx];
|
||||
out_idx++;
|
||||
}
|
||||
|
||||
ms_counter_[sat] = (ms_counter_[sat] + (int)round(1e3*Galileo_E1_CODE_PERIOD))
|
||||
% data_bit_duration_ms_[sat];
|
||||
}
|
||||
if (ms_counter_[sat] == 0 && data_flag_)
|
||||
{
|
||||
// New random data bit
|
||||
current_data_bits_[sat] = gr_complex((rand()%2) == 0 ? 1 : -1, 0);
|
||||
}
|
||||
|
||||
for (k = delay_samples; k < samples_per_code_[sat]; k++)
|
||||
{
|
||||
out[out_idx] += (sampled_code_data_[sat][out_idx] * current_data_bits_[sat]
|
||||
- sampled_code_pilot_[sat][out_idx])
|
||||
* complex_phase_[out_idx];
|
||||
out_idx++;
|
||||
}
|
||||
|
||||
|
||||
ms_counter_[sat] = (ms_counter_[sat] + (int)round(1e3*Galileo_E1_CODE_PERIOD))
|
||||
% data_bit_duration_ms_[sat];
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,4 +450,3 @@ int signal_generator_c::general_work (int noutput_items,
|
||||
// Tell runtime system how many output items we produced.
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#ifndef GNSS_SDR_SIGNAL_GENERATOR_C_H
|
||||
#define GNSS_SDR_SIGNAL_GENERATOR_C_H
|
||||
|
||||
/*
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <boost/scoped_array.hpp>
|
||||
@@ -52,7 +52,7 @@ class signal_generator_c;
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
*/
|
||||
*//*
|
||||
typedef boost::shared_ptr<signal_generator_c> signal_generator_c_sptr;
|
||||
|
||||
/*!
|
||||
@@ -61,9 +61,9 @@ typedef boost::shared_ptr<signal_generator_c> signal_generator_c_sptr;
|
||||
* To avoid accidental use of raw pointers, gen_source's
|
||||
* constructor is private. signal_make_generator_c is the public
|
||||
* interface for creating new instances.
|
||||
*/
|
||||
*//*
|
||||
signal_generator_c_sptr
|
||||
signal_make_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
signal_make_generator_c (std::vector<std::string> system, std::vector<std::string> _signal, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB);
|
||||
@@ -73,21 +73,21 @@ signal_make_generator_c (std::vector<std::string> system, const std::vector<unsi
|
||||
* \ingroup block
|
||||
*
|
||||
* \sa gen_source for a version that subclasses gr_block.
|
||||
*/
|
||||
*//*
|
||||
class signal_generator_c : public gr::block
|
||||
{
|
||||
private:
|
||||
// The friend declaration allows gen_source to
|
||||
// access the private constructor.
|
||||
|
||||
/* Create the signal_generator_c object*/
|
||||
/* Create the signal_generator_c object*//*
|
||||
friend signal_generator_c_sptr
|
||||
signal_make_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
signal_make_generator_c (std::vector<std::string> system, std::vector<std::string> signal, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB);
|
||||
|
||||
signal_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
signal_generator_c (std::vector<std::string> system,std::vector<std::string> signal, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB);
|
||||
@@ -96,6 +96,7 @@ private:
|
||||
void generate_codes();
|
||||
|
||||
std::vector<std::string> system_;
|
||||
std::vector<std::string> signal_;
|
||||
std::vector<unsigned int> PRN_;
|
||||
std::vector<float> CN0_dB_;
|
||||
std::vector<float> doppler_Hz_;
|
||||
@@ -130,4 +131,112 @@ public:
|
||||
gr_vector_void_star &output_items);
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <gnuradio/random.h>
|
||||
#include <gnuradio/block.h>
|
||||
#include "gnss_signal.h"
|
||||
|
||||
|
||||
|
||||
|
||||
class signal_generator_c;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues.
|
||||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<signal_generator_c> signal_generator_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of gen_source.
|
||||
*
|
||||
* To avoid accidental use of raw pointers, gen_source's
|
||||
* constructor is private. signal_make_generator_c is the public
|
||||
* interface for creating new instances.
|
||||
*/
|
||||
signal_generator_c_sptr
|
||||
signal_make_generator_c (std::vector<std::string> signal1, std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB);
|
||||
|
||||
/*!
|
||||
* \brief This class generates synthesized GNSS signal.
|
||||
* \ingroup block
|
||||
*
|
||||
* \sa gen_source for a version that subclasses gr_block.
|
||||
*/
|
||||
class signal_generator_c : public gr::block
|
||||
{
|
||||
private:
|
||||
// The friend declaration allows gen_source to
|
||||
// access the private constructor.
|
||||
|
||||
/* Create the signal_generator_c object*/
|
||||
friend signal_generator_c_sptr
|
||||
signal_make_generator_c (std::vector<std::string> signal1, std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB);
|
||||
|
||||
signal_generator_c (std::vector<std::string> signal1, std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB);
|
||||
|
||||
void init();
|
||||
void generate_codes();
|
||||
|
||||
std::vector<std::string> signal_;
|
||||
std::vector<std::string> system_;
|
||||
std::vector<unsigned int> PRN_;
|
||||
std::vector<float> CN0_dB_;
|
||||
std::vector<float> doppler_Hz_;
|
||||
std::vector<unsigned int> delay_chips_;
|
||||
bool data_flag_;
|
||||
bool noise_flag_;
|
||||
unsigned int fs_in_;
|
||||
unsigned int num_sats_;
|
||||
unsigned int vector_length_;
|
||||
float BW_BB_;
|
||||
|
||||
std::vector<unsigned int> samples_per_code_;
|
||||
std::vector<unsigned int> num_of_codes_per_vector_;
|
||||
std::vector<unsigned int> data_bit_duration_ms_;
|
||||
std::vector<unsigned int> ms_counter_;
|
||||
std::vector<float> start_phase_rad_;
|
||||
std::vector<gr_complex> current_data_bits_;
|
||||
std::vector<signed int> current_data_bit_int_;
|
||||
std::vector<signed int> data_modulation_;
|
||||
std::vector<signed int> pilot_modulation_;
|
||||
|
||||
boost::scoped_array<gr_complex*> sampled_code_data_;
|
||||
boost::scoped_array<gr_complex*> sampled_code_pilot_;
|
||||
gr::random* random_;
|
||||
gr_complex* complex_phase_;
|
||||
|
||||
unsigned int work_counter_;
|
||||
|
||||
public:
|
||||
~signal_generator_c (); // public destructor
|
||||
|
||||
// Where all the action really happens
|
||||
|
||||
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 /* GNSS_SDR_SIGNAL_GENERATOR_C_H */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user