mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-09-27 23:24:04 +00:00
Working version of p-code plus tests
Note that there is an error in IS GPS 200 H, which is where we get the testvectors from. This commit passes against test vectors from the proposed modification: IS GPS 200 H PIRN 001
This commit is contained in:
@@ -172,14 +172,14 @@ const unsigned int GPS_P_Code_Generator::X2B_EXTRA_LENGTH = 965;
|
||||
const unsigned int GPS_P_Code_Generator::X2A_EPOCHS_LAST_X2_EPOCH = 104;
|
||||
const unsigned int GPS_P_Code_Generator::X2B_EPOCHS_LAST_X2_EPOCH = 104;
|
||||
|
||||
void GPS_P_Code_Generator::get_chips( int sv, uint64_t first_chip_index, unsigned num_chips,
|
||||
void GPS_P_Code_Generator::get_chips( int prn, uint64_t first_chip_index, unsigned num_chips,
|
||||
std::vector< short > &_dest ) const
|
||||
{
|
||||
// A couple of quick checks:
|
||||
if( sv < 1 or sv > 37 )
|
||||
if( prn < 1 or prn > 210 )
|
||||
{
|
||||
LOG(ERROR) << "Invalid SV number: " << sv
|
||||
<< " should be in the range 1 to 37 (inclusive)";
|
||||
LOG(ERROR) << "Invalid SV number: " << prn
|
||||
<< " should be in the range 1 to 210 (inclusive)";
|
||||
}
|
||||
|
||||
if( first_chip_index > GPS_P_CODE_LENGTH_CHIPS )
|
||||
@@ -197,6 +197,14 @@ void GPS_P_Code_Generator::get_chips( int sv, uint64_t first_chip_index, unsigne
|
||||
}
|
||||
|
||||
// OK now we can proceed:
|
||||
// IS GPS 200H - The first 37 PRN codes are unique, identified by sv
|
||||
// below. For PRN values greater than 37 we create the code for
|
||||
// (prn-1) % 37 + 1 and delay it by floor( (prn-1)/37 ) days
|
||||
int sv = ( prn - 1 ) % 37 + 1;
|
||||
int num_days = (prn-1) / 37;
|
||||
uint64_t day_shift = num_days*10230000LL*24LL*3600LL;
|
||||
first_chip_index = first_chip_index + day_shift;
|
||||
first_chip_index %= GPS_P_CODE_LENGTH_CHIPS;
|
||||
|
||||
//Ensure we have space:
|
||||
_dest.resize( num_chips );
|
||||
@@ -204,7 +212,7 @@ void GPS_P_Code_Generator::get_chips( int sv, uint64_t first_chip_index, unsigne
|
||||
|
||||
// Establish the starting phase:
|
||||
// 1) account for the delay of the x2 register
|
||||
int64_t first_chip_index_x2 = first_chip_index - sv + 1;
|
||||
int64_t first_chip_index_x2 = first_chip_index - sv;
|
||||
while( first_chip_index_x2 < 0 )
|
||||
{
|
||||
first_chip_index_x2 += GPS_P_CODE_LENGTH_CHIPS;
|
||||
@@ -293,11 +301,14 @@ void GPS_P_Code_Generator::get_chips( int sv, uint64_t first_chip_index, unsigne
|
||||
extra_code_period = X2A_EXTRA_LENGTH;
|
||||
}
|
||||
|
||||
if( x2a_epoch >= max_num_epochs )
|
||||
if( x2a_epoch >= max_num_epochs-1 )
|
||||
{
|
||||
this_code_period = this_code_period + extra_code_period;
|
||||
x2a_ind += GPS_X2A_CODE_LENGTH;
|
||||
x2a_epoch--;
|
||||
if( x2a_epoch == max_num_epochs )
|
||||
{
|
||||
x2a_ind += GPS_X2A_CODE_LENGTH;
|
||||
}
|
||||
x2a_epoch = max_num_epochs-1;
|
||||
}
|
||||
|
||||
unsigned int chips_to_gen = std::min( num_chips - dest_ind,
|
||||
@@ -345,11 +356,14 @@ void GPS_P_Code_Generator::get_chips( int sv, uint64_t first_chip_index, unsigne
|
||||
extra_code_period = X2B_EXTRA_LENGTH;
|
||||
}
|
||||
|
||||
if( x2b_epoch >= max_num_epochs )
|
||||
if( x2b_epoch >= max_num_epochs - 1 )
|
||||
{
|
||||
this_code_period = this_code_period + extra_code_period;
|
||||
x2b_ind += GPS_X2B_CODE_LENGTH;
|
||||
x2b_epoch--;
|
||||
if( x2b_epoch == max_num_epochs )
|
||||
{
|
||||
x2b_ind += GPS_X2B_CODE_LENGTH;
|
||||
}
|
||||
x2b_epoch = max_num_epochs - 1;
|
||||
}
|
||||
|
||||
unsigned int chips_to_gen = std::min( num_chips - dest_ind,
|
||||
|
@@ -34,12 +34,75 @@
|
||||
#include "GPS_P_CODE.h"
|
||||
#include "gps_pcode.h"
|
||||
|
||||
// Test vectors from IS GPS 200 H
|
||||
// Note there are some errors in that document as per:
|
||||
//http://www.gps.gov/technical/icwg/meetings/2015/PIRN-IS-200H-001.pdf
|
||||
// in particular:
|
||||
// PRN : OLD : NEW
|
||||
// 66 : 2111 : 6111
|
||||
// 69 : 4166 : 0166
|
||||
// 70 : 2251 : 6251
|
||||
|
||||
const std::vector< short > first_12_chips_octal = {
|
||||
04444, 04000, 04222, 04333, 04377, 04355, 04344, 04340, 04342, 04343,
|
||||
04343, 04343, 04343, 04343, 04343, 04343, 04343, 04343, 04343, 04343,
|
||||
04343, 04343, 04343, 04343, 04343, 04343, 04343, 04343, 04343, 04343,
|
||||
04343, 04343, 04343, 04343, 04343, 04343, 04343, // <-- 37
|
||||
03373, 03757, 07545, 05440, 04402, 04023, 00233, 02337, 03375, 03754,
|
||||
03544, 07440, 01402, 06423, 01033, 02637, 07135, 05674, 00514, 06064,
|
||||
01210, 06726, 01171, 06656, 01105, 06660, // <-- 63
|
||||
/* IS GPS 200 H:
|
||||
05112, 00667, 02111, 05266, 04711, 04166, 02251, 05306, 04761, 02152,
|
||||
05247, 05736, 02575, 03054, 03604, 03520, 05472, 04417, 02025, 03230,
|
||||
05736, 04575, 02054, 03204, 03720, 05572, 04457, 04005, 02220, 03332,
|
||||
03777, 03555, // <- 95
|
||||
03444, 07400, 01422, 02433, 07037, 01635, 06534, 05074, 00614, 06124,
|
||||
01270, 02716, 05165, 00650, 06106, 05261, 06752, 05147, 00641, 06102,
|
||||
01263, 02713, 03167, 03651, 07506, 05461, 00412, 06027, 01231, 02736, // <-125
|
||||
07175, 01654, 06504, 01060, 02612, 07127, 05671, 04516, 04065, 04210,
|
||||
04326, 00371, 06356, 05345, 00740, 06142, 01243, 06703, 05163, 04653,
|
||||
04107, 04261, 00312, 02525, 07070, 01616, 02525, 07070, 03616, 07525, // <- 155
|
||||
05470, 04416, 04025, 04230, 00336, 06375, 01354, 06744, 05140, 04642,
|
||||
00103, 06263, 01313, 06767, 01151, 02646, 07101, 05662, 00513, 02067,
|
||||
03211, 03726, 03571, 03456, 03405, 03420, 05432, 00437, 06035, 01234, // <- 185
|
||||
01067, 06611, 05126, 04671, 00116, 06265, 01310, 06766, 01151, 02646,
|
||||
03101, 07662, 05513, 04467, 04011, 04226, 04331, 00376, 06355, 05344,
|
||||
00740, 06142, 01243, 06703, 01163 //<- 210 */
|
||||
/* PRN IS GPS 200 H 001:*/
|
||||
05112, 00667, 06111, 05266, 04711, 00166, 06251, 05306, 00761, 06152,
|
||||
01247, 01736, 02575, 03054, 03604, 07520, 05472, 00417, 02025, 07230,
|
||||
05736, 00575, 02054, 03204, 07720, 05572, 04457, 00005, 02220, 03332,
|
||||
03777, 03555, 03444, 07400, 01422, 02433, 07037, 01635, 06534, 05074,
|
||||
00614, 06124, 01270, 06716, 05165, 00650, 06106, 05261, 06752, 05147,
|
||||
00641, 06102, 01263, 02713, 03167, 03651, 07506, 05461, 00412, 06027,
|
||||
01231, 02736, 07175, 01654, 06504, 01060, 02612, 07127, 05671, 04516,
|
||||
04065, 04210, 04326, 00371, 06356, 05345, 00740, 06142, 01243, 06703,
|
||||
05163, 04653, 04107, 04261, 00312, 02525, 07070, 01616, 02525, 03070,
|
||||
03616, 07525, 05470, 04416, 04025, 04230, 00336, 06375, 01354, 06744,
|
||||
05140, 04642, 00103, 06263, 01313, 06767, 01151, 02646, 07101, 05662,
|
||||
00513, 02067, 03211, 03726, 03571, 03456, 03405, 07420, 05432, 00437,
|
||||
06035, 01234, // <- 185
|
||||
01067, 06611, 05126, 04671, 00116, 06265, 01310, 06766, 01151, 02646,
|
||||
03101, 07662, 05513, 04467, 04011, 04226, 04331, 00376, 06355, 05344,
|
||||
00740, 06142, 01243, 06703, 01163 //<- 210 */
|
||||
};
|
||||
|
||||
|
||||
|
||||
TEST(PCodeGenTest, X1ATest)
|
||||
{
|
||||
std::vector< short > dest;
|
||||
|
||||
gps_x1a_code_gen( dest );
|
||||
|
||||
// IS GPS 200 H
|
||||
std::vector< short > first_12_chips = { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0 };
|
||||
|
||||
for( unsigned int ii = 0; ii < 12; ++ii )
|
||||
{
|
||||
EXPECT_EQ( dest[ii], first_12_chips[ii] ) << "ii: " << ii;
|
||||
}
|
||||
|
||||
// From Octave:
|
||||
std::vector< short > last12Bits = { 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0 };
|
||||
|
||||
@@ -56,6 +119,13 @@ TEST(PCodeGenTest, X1BTest)
|
||||
|
||||
gps_x1b_code_gen( dest );
|
||||
|
||||
// IS GPS 200 H
|
||||
std::vector< short > first_12_chips = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 };
|
||||
|
||||
for( unsigned int ii = 0; ii < 12; ++ii )
|
||||
{
|
||||
EXPECT_EQ( dest[ii], first_12_chips[ii] ) << "ii: " << ii;
|
||||
}
|
||||
// From Octave:
|
||||
std::vector< short > last12Bits = { 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0 };
|
||||
|
||||
@@ -73,6 +143,14 @@ TEST(PCodeGenTest, X2ATest)
|
||||
|
||||
gps_x2a_code_gen( dest );
|
||||
|
||||
// IS GPS 200 H
|
||||
std::vector< short > first_12_chips = { 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1};
|
||||
|
||||
for( unsigned int ii = 0; ii < 12; ++ii )
|
||||
{
|
||||
EXPECT_EQ( dest[ii], first_12_chips[ii] ) << "ii: " << ii;
|
||||
}
|
||||
|
||||
// From Octave:
|
||||
std::vector< short > last12Bits = {0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1};
|
||||
|
||||
@@ -90,7 +168,16 @@ TEST(PCodeGenTest, X2BTest)
|
||||
|
||||
gps_x2b_code_gen( dest );
|
||||
|
||||
// From Octave:
|
||||
// IS GPS 200 H
|
||||
std::vector< short > first_12_chips = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 };
|
||||
|
||||
for( unsigned int ii = 0; ii < 12; ++ii )
|
||||
{
|
||||
EXPECT_EQ( dest[ii], first_12_chips[ii] ) << "ii: " << ii;
|
||||
}
|
||||
|
||||
|
||||
// From Octave :
|
||||
std::vector< short > last12Bits = {0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0};
|
||||
|
||||
for( unsigned int ii = 0; ii < 12; ++ii )
|
||||
@@ -101,7 +188,7 @@ TEST(PCodeGenTest, X2BTest)
|
||||
}
|
||||
|
||||
|
||||
TEST(PCodeGenTest, FirstChipsTest)
|
||||
TEST(PCodeGenTest, FirstChipsTest1)
|
||||
{
|
||||
std::vector< short > dest;
|
||||
|
||||
@@ -120,20 +207,50 @@ TEST(PCodeGenTest, FirstChipsTest)
|
||||
unsigned int num_chips = 24;
|
||||
|
||||
int sv = 1;
|
||||
int first_chip_index = sv;
|
||||
|
||||
pcode_gen.get_chips( sv, 0, num_chips, dest );
|
||||
pcode_gen.get_chips( sv, first_chip_index, num_chips, dest );
|
||||
|
||||
EXPECT_EQ( dest.size(), num_chips );
|
||||
|
||||
for( unsigned ii = 0; ii < num_chips; ++ii )
|
||||
for( unsigned ii = 0, jj = first_chip_index; ii < num_chips; ++ii, ++jj)
|
||||
{
|
||||
short res = x1a[ii] ^ x1b[ii] ^ x2a[ii] ^ x2b[ii];
|
||||
short res = x1a[jj] ^ x1b[jj] ^ x2a[jj-sv] ^ x2b[jj-sv];
|
||||
|
||||
EXPECT_EQ( dest[ii], res );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST(PCodeGenTest, First12ChipsAll )
|
||||
{
|
||||
std::vector< short > dest;
|
||||
|
||||
GPS_P_Code_Generator pcode_gen;
|
||||
|
||||
unsigned int num_chips = 12;
|
||||
|
||||
int num_err = 0;
|
||||
for( int sv = 1; sv <= 210; ++sv )
|
||||
{
|
||||
pcode_gen.get_chips( sv, 0, num_chips, dest );
|
||||
short res = 0;
|
||||
for( int ii=0; ii < num_chips; ++ii )
|
||||
{
|
||||
//short theBit = ( first_12_chips_octal[ sv - 1 ] >> (11-ii) ) & 0x01;
|
||||
res = (res<<1) | dest[ii];
|
||||
|
||||
//EXPECT_EQ( dest[ii], theBit ) << " sv " << sv << " bit " << ii;
|
||||
}
|
||||
short icd = first_12_chips_octal[ sv - 1];
|
||||
EXPECT_EQ( res, icd ) << " sv " << sv << ". icd: " << std::oct << icd
|
||||
<< ". actual: " << std::oct << res << std::dec << ". num_err: " << ++num_err;
|
||||
}
|
||||
|
||||
EXPECT_EQ( num_err, 0 );
|
||||
|
||||
}
|
||||
|
||||
TEST(PCodeGenTest, EndX1EpochTest)
|
||||
{
|
||||
std::vector< short > dest;
|
||||
@@ -163,7 +280,7 @@ TEST(PCodeGenTest, EndX1EpochTest)
|
||||
for( unsigned ii = 0; ii < num_chips; ++ii )
|
||||
{
|
||||
short res = x1a[4092-num_chips+ii]
|
||||
^ x1b[4092] ^ x2a[4092-num_chips+ii]
|
||||
^ x1b[4092] ^ x2a[4092-num_chips+ii-sv]
|
||||
^ x2b[4092];
|
||||
|
||||
EXPECT_EQ( dest[ii], res );
|
||||
@@ -188,19 +305,36 @@ TEST(PCodeGenTest, StartSecondX1EpochTest)
|
||||
|
||||
unsigned int num_chips = 24;
|
||||
uint64_t end_x1_epoch = 4092LL*3750LL;
|
||||
uint64_t start_ind = end_x1_epoch;
|
||||
|
||||
int sv = 1;
|
||||
|
||||
uint64_t start_ind = end_x1_epoch;
|
||||
|
||||
pcode_gen.get_chips( sv, start_ind, num_chips, dest );
|
||||
|
||||
EXPECT_EQ( dest.size(), num_chips );
|
||||
|
||||
for( unsigned ii = 0; ii < num_chips; ++ii )
|
||||
unsigned ii = 0;
|
||||
for( ii = 0; ii < sv && ii < num_chips; ++ii )
|
||||
{
|
||||
short res = x1a[ii] ^ x1b[ii]
|
||||
^ x2a[4092-sv + ii] ^ x2b[ 4092 ];
|
||||
|
||||
EXPECT_EQ( dest[ii], res );
|
||||
}
|
||||
|
||||
for( ; (ii - sv ) < 37 && ii < num_chips; ++ii )
|
||||
{
|
||||
short res = x1a[ii] ^ x1b[ii]
|
||||
^ x2a[ 4091 ] ^ x2b[ 4092 ];
|
||||
EXPECT_EQ( dest[ii], res );
|
||||
}
|
||||
|
||||
for( ; ii < num_chips; ++ii )
|
||||
{
|
||||
short res = x1a[ii]
|
||||
^ x1b[ii] ^ x2a[4091]
|
||||
^ x2b[4092];
|
||||
^ x1b[ii] ^ x2a[ii-37-sv]
|
||||
^ x2b[ii-37-sv];
|
||||
|
||||
EXPECT_EQ( dest[ii], res );
|
||||
}
|
||||
@@ -259,7 +393,7 @@ TEST(PCodeGenTest, Prn37Test)
|
||||
GPS_P_Code_Generator pcode_gen;
|
||||
|
||||
int sv = 37;
|
||||
unsigned int num_chips = 24+sv-1;
|
||||
unsigned int num_chips = 24+sv;
|
||||
uint64_t start_ind = 0;
|
||||
|
||||
|
||||
@@ -267,13 +401,54 @@ TEST(PCodeGenTest, Prn37Test)
|
||||
|
||||
EXPECT_EQ( dest.size(), num_chips );
|
||||
|
||||
for( unsigned ii = sv-1; ii < num_chips; ++ii )
|
||||
for( unsigned ii = sv; ii < num_chips; ++ii )
|
||||
{
|
||||
short res = x1a[ii]
|
||||
^ x1b[ii] ^ x2a[ii-sv+1]
|
||||
^ x2b[ii-sv+1];
|
||||
^ x1b[ii] ^ x2a[ii-sv]
|
||||
^ x2b[ii-sv];
|
||||
|
||||
EXPECT_EQ( dest[ii], res );
|
||||
}
|
||||
}
|
||||
|
||||
TEST(PCodeGenTest, NewPrnTest)
|
||||
{
|
||||
std::vector< short > dest;
|
||||
std::vector< short > dest0;
|
||||
|
||||
GPS_P_Code_Generator pcode_gen;
|
||||
|
||||
int sv = 137;
|
||||
unsigned int num_chips = 24;
|
||||
uint64_t start_ind = 0;
|
||||
|
||||
int prn0 = (sv-1)%37 + 1;
|
||||
int day_shift = (sv-1)/37;
|
||||
|
||||
uint64_t start_ind0 = start_ind + day_shift*10230000LL*24LL*3600LL;
|
||||
|
||||
|
||||
pcode_gen.get_chips( sv, start_ind, num_chips, dest );
|
||||
pcode_gen.get_chips( prn0, start_ind0, num_chips, dest0 );
|
||||
|
||||
EXPECT_EQ( dest.size(), num_chips );
|
||||
EXPECT_EQ( dest0.size(), num_chips );
|
||||
|
||||
for( unsigned ii = 0; ii < num_chips; ++ii )
|
||||
{
|
||||
EXPECT_EQ( dest[ii], dest0[ii] );
|
||||
}
|
||||
|
||||
// From the IS GPS 200H:
|
||||
// PRN = 137: first 12 chips = o0371 (octal)
|
||||
// 0 0 0 0 1 1 1 1 1 0 0 1
|
||||
std::vector< short > first_12_chips_icd = {
|
||||
0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1
|
||||
};
|
||||
|
||||
for( unsigned int ii = 0; ii < 12; ++ii )
|
||||
{
|
||||
EXPECT_EQ( dest[ii], first_12_chips_icd[ii] );
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user