mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-12-04 07:38:08 +00:00
Added file_long_code_generator
For now this reads chips from an ASCII text file, which is not very efficient.
This commit is contained in:
@@ -34,6 +34,7 @@ set(GNSS_SPLIBS_SOURCES
|
||||
gps_pcode.cc
|
||||
gps_pcode_generator.cc
|
||||
spirent_prs_code_generator.cc
|
||||
file_long_code_generator.cc
|
||||
)
|
||||
|
||||
|
||||
|
||||
132
src/algorithms/libs/file_long_code_generator.cc
Normal file
132
src/algorithms/libs/file_long_code_generator.cc
Normal file
@@ -0,0 +1,132 @@
|
||||
/*!
|
||||
* \file file_long_code_generator.cc
|
||||
* \brief Defines a code generator conforming to the long_code_interface that
|
||||
* reads the chips from a file.
|
||||
* \author Cillian O'Driscoll, 2016. cillian.odriscoll(at)gmail.com
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2016 (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 "file_long_code_generator.h"
|
||||
#include <algorithm>
|
||||
#include <glog/logging.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
FileLongCodeGenerator::FileLongCodeGenerator( int sv, std::istream &is )
|
||||
{
|
||||
set_prn( sv );
|
||||
|
||||
initialise( is );
|
||||
}
|
||||
|
||||
bool FileLongCodeGenerator::get_chips( uint64_t first_chip_index, unsigned int num_chips,
|
||||
std::vector< short >& dest )
|
||||
{
|
||||
if( first_chip_index < d_first_chip_index ||
|
||||
first_chip_index > d_first_chip_index + d_num_chips ||
|
||||
first_chip_index + num_chips < d_first_chip_index )
|
||||
{
|
||||
LOG(INFO) << "Attempted to access chips outside of range. [" << first_chip_index
|
||||
<< ", " << first_chip_index+num_chips << "] not in [" << d_first_chip_index
|
||||
<< ", " << d_first_chip_index+d_num_chips << "]";
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t first_chip_to_return = std::max( d_first_chip_index,
|
||||
first_chip_index ) - d_first_chip_index;
|
||||
uint64_t last_chip_to_return = std::min( first_chip_index + num_chips,
|
||||
d_first_chip_index + d_num_chips ) - d_first_chip_index;
|
||||
|
||||
uint64_t num_chips_to_return = last_chip_to_return - first_chip_to_return
|
||||
+ 1;
|
||||
|
||||
dest.resize( num_chips_to_return );
|
||||
|
||||
LOG(INFO) << "Getting chips: " << first_chip_to_return
|
||||
<< " to " << last_chip_to_return;
|
||||
|
||||
std::copy( d_the_chips.begin() + first_chip_to_return,
|
||||
d_the_chips.begin() + last_chip_to_return + 1,
|
||||
dest.begin() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileLongCodeGenerator::set_prn( int sv )
|
||||
{
|
||||
d_sv = sv;
|
||||
}
|
||||
|
||||
uint64_t FileLongCodeGenerator::get_code_length( void ) const
|
||||
{
|
||||
return d_code_length;
|
||||
}
|
||||
|
||||
void FileLongCodeGenerator::initialise( std::istream &is )
|
||||
{
|
||||
// go to the beginning of the stream:
|
||||
is.seekg(0);
|
||||
|
||||
// The file format is:
|
||||
// FIRST_CHIP_INDEX
|
||||
// CODE_LENGTH
|
||||
// CHIP_0
|
||||
// CHIP_1
|
||||
// ...
|
||||
// CHIP_N-1
|
||||
// [Blank line]
|
||||
|
||||
// Handy algorithm for counting lines
|
||||
uint64_t numLines =
|
||||
std::count(std::istreambuf_iterator<char>(is),
|
||||
std::istreambuf_iterator<char>(), '\n');
|
||||
|
||||
if( numLines <= 3 )
|
||||
{
|
||||
LOG(ERROR) << "Invalid file format: expected at least 3 lines";
|
||||
}
|
||||
|
||||
d_num_chips = numLines - 3; // First two lines and last blank line
|
||||
|
||||
d_the_chips.resize( d_num_chips );
|
||||
|
||||
is.seekg(0);
|
||||
|
||||
is >> d_first_chip_index;
|
||||
is >> d_code_length;
|
||||
|
||||
uint64_t ii = 0;
|
||||
|
||||
while( is >> d_the_chips[ii++] ){};
|
||||
|
||||
if( ii < d_num_chips )
|
||||
{
|
||||
LOG(ERROR) << "Expected " << d_num_chips << " chips, only read "
|
||||
<< ii;
|
||||
}
|
||||
|
||||
}
|
||||
67
src/algorithms/libs/file_long_code_generator.h
Normal file
67
src/algorithms/libs/file_long_code_generator.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*!
|
||||
* \file file_long_code_generator.h
|
||||
* \brief Defines a code generator conforming to the long_code_interface that
|
||||
* reads the chips from a file.
|
||||
* \author Cillian O'Driscoll, 2016. cillian.odriscoll(at)gmail.com
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2016 (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 GNSS_SDR_FILE_LONG_CODE_GENERATOR_H_
|
||||
#define GNSS_SDR_FILE_LONG_CODE_GENERATOR_H_
|
||||
|
||||
#include "long_code_interface.h"
|
||||
#include <istream>
|
||||
|
||||
class FileLongCodeGenerator : public LongCodeInterface
|
||||
{
|
||||
public:
|
||||
FileLongCodeGenerator( int sv, std::istream &is );
|
||||
|
||||
bool get_chips( uint64_t first_chip_index,
|
||||
unsigned int num_chips,
|
||||
std::vector< short >& dest );
|
||||
|
||||
void set_prn( int sv );
|
||||
|
||||
uint64_t get_code_length( void ) const;
|
||||
|
||||
private:
|
||||
|
||||
int d_sv;
|
||||
|
||||
uint64_t d_first_chip_index;
|
||||
uint64_t d_num_chips;
|
||||
uint64_t d_code_length;
|
||||
|
||||
std::vector< short > d_the_chips;
|
||||
|
||||
void initialise( std::istream &is );
|
||||
|
||||
};
|
||||
|
||||
#endif // GNSS_SDR_PCODE_GENERATOR_H_
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "Galileo_E1.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "spirent_prs_code_generator.h"
|
||||
#include "file_long_code_generator.h"
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
@@ -112,6 +113,31 @@ GalileoE1PrsDeTracking::GalileoE1PrsDeTracking(
|
||||
LOG(ERROR) << "Unable to create a SpirentPrsCodeGenerator";
|
||||
}
|
||||
}
|
||||
else if( not code_type.compare("File") )
|
||||
{
|
||||
std::string code_file_name = configuration->property( role + ".prs_code_file", std::string(""));
|
||||
|
||||
if( code_file_name == "" )
|
||||
{
|
||||
LOG(ERROR) << "prs_code_file configuration property missing";
|
||||
}
|
||||
|
||||
std::ifstream prs_code_file( code_file_name );
|
||||
|
||||
if( not prs_code_file.is_open() )
|
||||
{
|
||||
LOG(ERROR) << "Unable to open prs_code_file: " << code_file_name;
|
||||
}
|
||||
|
||||
code_gen = boost::shared_ptr< LongCodeInterface>(
|
||||
new FileLongCodeGenerator( 1, prs_code_file )
|
||||
);
|
||||
|
||||
if( code_gen == 0 )
|
||||
{
|
||||
LOG(ERROR) << "Unable to create a FileLongCodeGenerator";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(ERROR) << code_type << " unknown PRS code type";
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "Galileo_E1.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "spirent_prs_code_generator.h"
|
||||
#include "file_long_code_generator.h"
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
@@ -112,6 +113,31 @@ GalileoE1PrsVemlTracking::GalileoE1PrsVemlTracking(
|
||||
LOG(ERROR) << "Unable to create a SpirentPrsCodeGenerator";
|
||||
}
|
||||
}
|
||||
else if( not code_type.compare("File") )
|
||||
{
|
||||
std::string code_file_name = configuration->property( role + ".prs_code_file", std::string(""));
|
||||
|
||||
if( code_file_name == "" )
|
||||
{
|
||||
LOG(ERROR) << "prs_code_file configuration property missing";
|
||||
}
|
||||
|
||||
std::ifstream prs_code_file( code_file_name );
|
||||
|
||||
if( not prs_code_file.is_open() )
|
||||
{
|
||||
LOG(ERROR) << "Unable to open prs_code_file: " << code_file_name;
|
||||
}
|
||||
|
||||
code_gen = boost::shared_ptr< LongCodeInterface>(
|
||||
new FileLongCodeGenerator( 1, prs_code_file )
|
||||
);
|
||||
|
||||
if( code_gen == 0 )
|
||||
{
|
||||
LOG(ERROR) << "Unable to create a FileLongCodeGenerator";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(ERROR) << code_type << " unknown PRS code type";
|
||||
|
||||
@@ -252,7 +252,6 @@ add_executable(gnss_block_test
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/flowgraph/pass_through_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/file_output_filter_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/arithmetic/pcode_generation_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/arithmetic/spirent_prs_code_generation_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/gnss_block_factory_test.cc
|
||||
)
|
||||
if(NOT ${ENABLE_PACKAGING})
|
||||
@@ -376,6 +375,8 @@ add_executable(arithmetic_test
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/arithmetic/code_resampler_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/arithmetic/subcarrier_resampler_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/arithmetic/accumulate_array_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/arithmetic/spirent_prs_code_generation_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/arithmetic/file_long_code_generator_test.cc
|
||||
)
|
||||
if(NOT ${ENABLE_PACKAGING})
|
||||
set_property(TARGET arithmetic_test PROPERTY EXCLUDE_FROM_ALL TRUE)
|
||||
|
||||
185
src/tests/arithmetic/file_long_code_generator_test.cc
Normal file
185
src/tests/arithmetic/file_long_code_generator_test.cc
Normal file
@@ -0,0 +1,185 @@
|
||||
/*!
|
||||
* \file file_long_code_generation_test.cc
|
||||
* \brief This file implements tests for the generation of the long codes
|
||||
* whose chips are read from file
|
||||
* \author Cillian O'Driscoll, 2016. cillian.odriscoll(at)gmail.com
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2016 (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 <gtest/gtest.h>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include "file_long_code_generator.h"
|
||||
|
||||
const uint64_t kFirstChipInd = 204900;
|
||||
const uint64_t kCodeLength = 1023000*2.5*3600*24*7;
|
||||
const std::vector< short > kChipVec = { 1, 1, -1, -1, +1, -1, +1, -1, +1, +1 };
|
||||
|
||||
class FileLongCodeTestGen : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
FileLongCodeTestGen()
|
||||
: ios("")
|
||||
{
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual void SetUp()
|
||||
{
|
||||
ios << kFirstChipInd << std::endl;
|
||||
ios << kCodeLength << std::endl;
|
||||
for( std::vector< short >::const_iterator it = kChipVec.begin();
|
||||
it != kChipVec.end(); ++it )
|
||||
{
|
||||
ios << *it << std::endl;
|
||||
}
|
||||
|
||||
ios.seekg( 0 );
|
||||
}
|
||||
|
||||
std::stringstream ios;
|
||||
|
||||
};
|
||||
|
||||
|
||||
TEST_F(FileLongCodeTestGen, CheckFileContents )
|
||||
{
|
||||
uint64_t firstChipIndex;
|
||||
|
||||
ios >> firstChipIndex;
|
||||
|
||||
EXPECT_EQ( kFirstChipInd, firstChipIndex );
|
||||
|
||||
uint64_t code_length;
|
||||
|
||||
ios >> code_length;
|
||||
|
||||
EXPECT_EQ( code_length, kCodeLength );
|
||||
|
||||
// Count the lines in the file:
|
||||
|
||||
ios.seekg( 0 );
|
||||
unsigned long numLines =
|
||||
std::count(std::istreambuf_iterator<char>(ios),
|
||||
std::istreambuf_iterator<char>(), '\n');
|
||||
|
||||
EXPECT_EQ( kChipVec.size() + 2, numLines );
|
||||
|
||||
}
|
||||
|
||||
TEST_F(FileLongCodeTestGen, GetKnownBits)
|
||||
{
|
||||
FileLongCodeGenerator codeGen( 1, ios );
|
||||
|
||||
std::vector< short > theChips;
|
||||
|
||||
bool res = codeGen.get_chips( kFirstChipInd, kChipVec.size(), theChips );
|
||||
|
||||
EXPECT_TRUE( res );
|
||||
|
||||
EXPECT_EQ( kChipVec.size(), theChips.size() );
|
||||
|
||||
for( unsigned int ii = 0; ii < theChips.size(); ++ii )
|
||||
{
|
||||
EXPECT_EQ( kChipVec[ii], theChips[ii] ) << "Chip error at index: " << ii;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_F(FileLongCodeTestGen, CantGetEarlyBits )
|
||||
{
|
||||
FileLongCodeGenerator codeGen( 1, ios );
|
||||
|
||||
std::vector< short > theChips;
|
||||
|
||||
bool res = codeGen.get_chips( kFirstChipInd - 1, kChipVec.size(), theChips );
|
||||
|
||||
EXPECT_FALSE( res );
|
||||
}
|
||||
|
||||
TEST_F(FileLongCodeTestGen, CanGetSomeBitsAtEnd )
|
||||
{
|
||||
FileLongCodeGenerator codeGen( 1, ios );
|
||||
|
||||
std::vector< short > theChips;
|
||||
|
||||
bool res = codeGen.get_chips( kFirstChipInd + kChipVec.size() - 3,
|
||||
kChipVec.size(), theChips );
|
||||
|
||||
EXPECT_TRUE( res );
|
||||
|
||||
EXPECT_EQ( 3, theChips.size() );
|
||||
|
||||
for( unsigned int ii = 0; ii < 3; ++ii )
|
||||
{
|
||||
EXPECT_EQ( kChipVec[ kChipVec.size()-3+ii ], theChips[ii] );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F( FileLongCodeTestGen, CantGetLateBits )
|
||||
{
|
||||
FileLongCodeGenerator codeGen( 1, ios );
|
||||
|
||||
std::vector< short > theChips;
|
||||
|
||||
bool res = codeGen.get_chips( kFirstChipInd + kChipVec.size(),
|
||||
kChipVec.size(), theChips );
|
||||
|
||||
EXPECT_FALSE( res );
|
||||
}
|
||||
|
||||
/*
|
||||
TEST_F( FileLongCodeTestGen, CanWorkFromFile )
|
||||
{
|
||||
std::ifstream ifs( "sample_file_long_code.txt" );
|
||||
|
||||
ASSERT_TRUE( ifs.is_open() );
|
||||
|
||||
FileLongCodeGenerator codeGen( 1, ifs );
|
||||
|
||||
EXPECT_EQ( 1546776000000, codeGen.get_code_length() );
|
||||
|
||||
uint64_t first_chip_index = 0;
|
||||
|
||||
ifs.clear();
|
||||
ifs.seekg( 0 );
|
||||
|
||||
ifs >> first_chip_index;
|
||||
|
||||
EXPECT_EQ( 564426801213, first_chip_index );
|
||||
|
||||
std::vector< short > the_chips;
|
||||
|
||||
bool res = codeGen.get_chips( first_chip_index, 10, the_chips );
|
||||
|
||||
EXPECT_TRUE( res );
|
||||
|
||||
EXPECT_EQ( 10, the_chips.size() );
|
||||
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user