1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-14 04:00:34 +00:00

GSoC 2013 commit from Mara Branzanti

git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@405 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
Javier Arribas 2013-08-17 18:13:20 +00:00
parent 367105f666
commit c4508f875f
4 changed files with 739 additions and 320 deletions

View File

@ -39,11 +39,15 @@
#include <glog/logging.h> #include <glog/logging.h>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include "control_message_factory.h" #include "control_message_factory.h"
#include "galileo_navigation_message.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "convolutional.h" #include "convolutional.h"
#include <stdio.h>
#include <stdlib.h>
using google::LogMessage; using google::LogMessage;
@ -286,15 +290,18 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
{ {
std::cout<<"Page Odd"<<std::endl; std::cout<<"Page Odd"<<std::endl;
d_nav.split_page(page_String.c_str(), flag_even_word_arrived); d_nav.split_page(page_String.c_str(), flag_even_word_arrived);
//decode_page.split_page(page_String, flag_even_word_arrived);
flag_even_word_arrived=0; flag_even_word_arrived=0;
std::cout<<"Page type ="<< page_part_bits[1]<<std::endl; std::cout << "page odd" << page_String << std::endl;
//std::cout<<"Page type ="<< page_part_bits[1]<<std::endl;
} }
else else
{ {
std::cout<<"Page Even"<<std::endl; std::cout<<"Page Even"<<std::endl;
d_nav.split_page(page_String.c_str(), flag_even_word_arrived); d_nav.split_page(page_String.c_str(), flag_even_word_arrived);
flag_even_word_arrived=1; flag_even_word_arrived=1;
std::cout<<"Page type ="<< page_part_bits[1]<<std::endl; std::cout << "page even" << std::endl << page_String << std::endl;
//std::cout<<"Page type ="<< page_part_bits[1]<<std::endl;
} }
// 4. Push the new navigation data to the queues // 4. Push the new navigation data to the queues

View File

@ -39,8 +39,6 @@
#include <cstring> #include <cstring>
#include <string> #include <string>
using namespace std;
typedef boost::crc_optimal<24, 0x1864CFBu, 0x0, 0x0, false, false> CRC_Galileo_INAV_type; typedef boost::crc_optimal<24, 0x1864CFBu, 0x0, 0x0, false, false> CRC_Galileo_INAV_type;
@ -119,13 +117,12 @@ void Galileo_Navigation_Message::reset()
Delta_tLSF_6 = 0; Delta_tLSF_6 = 0;
TOW_6 = 0; TOW_6 = 0;
/*Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number*/ /*Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number*/
IOD_a_7 = 0; IOD_a_7 = 0;
WN_a_7 = 0; WN_a_7 = 0;
t0a_7 = 0; t0a_7 = 0;
SVID1_7 = 0; SVID1_7 = 0;
Delta_alpha_7 = 0; DELTA_A_7 = 0;
e_7 = 0; e_7 = 0;
omega_7 = 0; omega_7 = 0;
delta_i_7 = 0; delta_i_7 = 0;
@ -173,6 +170,7 @@ void Galileo_Navigation_Message::reset()
af1_10 = 0; af1_10 = 0;
E5b_HS_10 = 0; E5b_HS_10 = 0;
E1B_HS_10 = 0; E1B_HS_10 = 0;
//GST-GPS
A_0G_10 = 0; A_0G_10 = 0;
A_1G_10 = 0; A_1G_10 = 0;
t_0G_10 = 0; t_0G_10 = 0;
@ -184,9 +182,6 @@ void Galileo_Navigation_Message::reset()
WN_0 = 0; WN_0 = 0;
TOW_0 = 0; TOW_0 = 0;
} }
@ -348,97 +343,60 @@ bool Galileo_Navigation_Message::read_navigation_bool(std::bitset<GALILEO_DATA_J
}*/ }*/
void Galileo_Navigation_Message::split_page(const char *page, int flag_even_word){ void Galileo_Navigation_Message::split_page(const char *page, int flag_even_word){
// ToDo: Replace all the C structures and string operations with std::string and std::stringstream C++ classes. // ToDo: Replace all the C structures and string operations with std::string and std::stringstream C++ classes.
// ToDo: Clean all the tests and create an independent google test code for the telemetry decoder. // ToDo: Clean all the tests and create an independent google test code for the telemetry decoder.
cout << "--------------------------------------------------------------------------" << endl;
cout << "Entered in Galileo_Navigation_Message::split_page(char *page)" << endl << endl;;
char Even_bit[2]={'\0'}, Odd_bit[2]={'\0'}, Page_type_Odd[2]={'\0'}, Page_type_even[2]={'\0'}, tail_Even[7]={'\0'}; //HO DATO A TUTTI UNO SPAZIO IN PIÙ PER L'ULTIMO CARATTERE std::cout << "Entered in Galileo_Navigation_Message::split_page(const char *page, int flag_even_word" << std::endl << std::endl;;
char page_Odd[121]={'\0'}; std::string page_string = page;
char page_INAV[235]={'\0'}; //char correct_tail[7]="011110"; //the viterbi decoder output change the tail to this value (why?)
char Data_j[16]={'\0'}, Data_k[112]={'\0'}, page_number_bits[6]={'\0'};
char Data_jk_ephemeris[129]={'\0'};
char Reserved_1[40]={'\0'};
char SAR[22]={'\0'};
char Spare[2]={'\0'};
char CRC_data[24]={'\0'}; char correct_tail[7]="000000";
char Reserved_2[8]={'\0'};
char Tail_odd[6]={'\0'};
//char correct_tail[7]="000000";
char correct_tail[7]="011110"; //the viterbi decoder output change the tail to this value (why?)
int Page_type=0; int Page_type=0;
static char page_Even[114]; static std::string page_Even; //declare in this way it can "remember the previous even page while reading the odd page..ok!
/* Test to decode page 1 even joined to its corresponding
The Even pages given here are without their tails bits*/
//test to detect page 1------> char page_Even[115]="000000010001011111010111101101100111110110101110101111100011001000000000001101110101110010000100101010100000010011";
//test to detect page 2------> char page_Even[115]="000000100001011111110010111010111100000010111100000010011100000000100001011110100111000111100111000000100000000010";
//test to detect page 3------>char page_Even[115]="000000110001011111111111111100001001100110001000110001011111110011111100110001011000111110000011011111000011110000";
//test to detect page 4------>char page_Even[115]="000001000001011111001100000000000000101100000000000111010101111011011000000001000101001111101010011100000000010110://
/*test to detect page 5------>char page_Even[115]="000001010010000010000000100010000010111010100000011111110001111111000111111001011000110010110011111111110110000000";*/
//test to detect page 10-----> char page_Even[115]="000010101111101010101010101010101010101010101010101010101010101010101010101010101010111100000000000000000000000000";
//test to detect page 6------>char page_Even[115]="000001100000000000000000000000011100001100000000000000000000000000100011010111111010001101000011100001000110101101
/* test to detect page 7------> char page_Even[115]="000001111111101001011111010011000000000110100000001110010111111110010111110111101001000001110000111111110000101101"; */
/* test to detect page 8------> char page_Even[115]="000010001111000000100001111100000011000001111010100000000000110100000001111010011110111000011110111101001000001110"; */
/* test to detect page 9------> char page_Even[115]="000010011111101001011111111000101110001100000000011010100000000010111111100000001010101010101010101010101010101010"; */
/* test to detect page 10------> char page_Even[115]="000010101111101010101010101010101010101010101010101010101010101010101010101010101010111100000000000000000000000000"; */
/* test to detect page 0------> char page_Even[115]="000000001001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010010110001100101";*/ std::cout << "Start decoding Galileo I/NAV " << std::endl;
cout << "Start decoding Galileo I/NAV " << endl;
// cout<<"page input"<<page<<endl;
cout<<page_Even<<endl;
;
if(page[0]=='1') // if page is odd
if(page_string.at(0)=='1')// if page is odd
{ {
std::cout<< "page[0] split page="<<page[0]<<endl; //std::cout<< "page_string.at(0) split page="<<page_string.at(0) << std::endl;
// std::cout << "Page Odd mara split page" << endl; std::string page_Odd = page_string; //chiamo la stringa sembre page_Odd
strcpy(page_Odd, page); //std::cout<<"Page odd string in split page"<< std::endl << page_Odd << std::endl;
std::cout<<"Page odd in split page"<< endl << page_Odd << endl;
if (flag_even_word==1) if (flag_even_word==1)/*Under this condition An odd page has been received but the previous even page is kept in memory and it is considered to join pages*/
{ {
/*Under this condition An odd page has been received but the previous even page in keep in memory and it is considered to join pages*/ //std::cout<<"previous page even "<< std::endl << page_Even << std::endl;
std::string page_INAV_even = page_Even;
strncpy(page_INAV, page_Even, 114); //Join pages: Even+Odd=INAV page //std::cout << "page inav solo even" << page_INAV_even << std::endl;
strncat(page_INAV, page_Odd,120); std::string page_INAV = page_INAV_even + page_Odd; //Join pages: Even+Odd=INAV page
//std::cout << "Page INAV Even+Odd " << endl << page_INAV << endl; //std::cout << "page inav eve +odd " << page_INAV<< std::endl;
std::string Even_bit = page_INAV.substr (0,1);
strncpy(Even_bit, &page_INAV[0], 1);
//std::cout << "Even bit = " << Even_bit << endl; //std::cout << "Even bit = " << Even_bit << endl;
strncpy(Page_type_even, &page_INAV[1], 1); std::string Page_type_even = page_INAV.substr (1,1);
//std::cout << "Page type even = " << Page_type_even << endl; //std::cout << "Page type even = " << Page_type_even << endl;
std::string nominal = "0";
if(atoi(Page_type_even)==1) std::cout << "Alert frame "<< endl; if (Page_type_even.compare(nominal) != 0)
else std::cout << "Nominal Page" << endl; std::cout << "Alert frame "<< std::endl;
else std::cout << "Nominal Page" << std::endl;
strncpy(Data_k, &page_INAV[2], 112); std::string Data_k = page_INAV.substr (2,112);
//std::cout << "Data_k " << endl << Data_k << endl; //std::cout << "Data_k " << endl << Data_k << endl;
std::string Odd_bit = page_INAV.substr (114,1);
strncpy(Odd_bit, &page_INAV[114], 1); std::string Page_type_Odd = page_INAV.substr (115,1);
//std::cout << "Odd bit: " << Odd_bit << endl;
strncpy(Page_type_Odd, &page_INAV[115], 1);
//std::cout << "Page_type_Odd: " << Page_type_Odd << endl; //std::cout << "Page_type_Odd: " << Page_type_Odd << endl;
strncpy(Data_j, &page_INAV[116], 16); std::string Data_j = page_INAV.substr (116,16);
//std::cout << "Data_j: " << endl << Data_j << endl; //std::cout << "Data_j: " << Data_j << endl;
strncpy(Reserved_1, &page_INAV[132], 40); std::string Reserved_1 = page_INAV.substr (132,40);
strncpy(SAR, &page_INAV[172], 22); std::string SAR = page_INAV.substr (172,22);
strncpy(Spare, &page_INAV[194], 2); std::string Spare = page_INAV.substr (194,2);
strncpy(CRC_data, &page_INAV[196], 24); std::string CRC_data = page_INAV.substr (196,24);
strncpy(Reserved_2, &page_INAV[220], 8); std::string Reserved_2 = page_INAV.substr (220,8);
strncpy(Tail_odd, &page_INAV[228], 6); std::string Tail_odd = page_INAV.substr (228,6);
std::cout << "tail odd: " << endl << Tail_odd << endl;
if(strcmp (Tail_odd,correct_tail) != 0)
std::cout << "Tail odd is not correct!" << endl;
else std::cout<<"Tail odd is correct!"<<endl;
//************ CRC checksum control *******/ //************ CRC checksum control *******/
std::stringstream TLM_word_for_CRC_stream; std::stringstream TLM_word_for_CRC_stream;
@ -452,6 +410,10 @@ void Galileo_Navigation_Message::split_page(const char *page, int flag_even_word
std::bitset<GALILEO_DATA_FRAME_BITS> TLM_word_for_CRC_bits(TLM_word_for_CRC); std::bitset<GALILEO_DATA_FRAME_BITS> TLM_word_for_CRC_bits(TLM_word_for_CRC);
std::bitset<24> checksum(CRC_data); std::bitset<24> checksum(CRC_data);
if (Tail_odd.compare(correct_tail) != 0)
std::cout << "Tail odd is not correct!" << std::endl;
else std::cout<<"Tail odd is correct!"<<std::endl;
if (CRC_test(TLM_word_for_CRC_bits,checksum.to_ulong())==true) if (CRC_test(TLM_word_for_CRC_bits,checksum.to_ulong())==true)
{ {
// CRC correct: Decode word // CRC correct: Decode word
@ -462,44 +424,30 @@ void Galileo_Navigation_Message::split_page(const char *page, int flag_even_word
} }
//********** end of CRC checksum control ***/ //********** end of CRC checksum control ***/
strncpy(page_number_bits, &Data_k[0], 6);
std::cout << "Page number bits from Data k" << endl << page_number_bits << endl;
stringstream ss_page_number; std::string page_number_bits = Data_k.substr (0,6);
string s_page_number; //std::cout << "Page number bits from Data k" << std::endl << page_number_bits << std::endl;
ss_page_number << page_number_bits; // from char to stringstream
ss_page_number >> s_page_number; // from stringstream to string
std::bitset<GALILEO_PAGE_TYPE_BITS> page_type_bits (s_page_number); // from string to bitset
std::bitset<GALILEO_PAGE_TYPE_BITS> page_type_bits (page_number_bits); // from string to bitset
Page_type = (int)read_page_type_unsigned(page_type_bits, type); Page_type = (int)read_page_type_unsigned(page_type_bits, type);
std::cout << "Page number (first 6 bits of Data k converted to decimal) = " << Page_type << std::endl;
std::cout << "Page number (first 6 bits of Data k converted to decimal) = " << Page_type << endl; std::string Data_jk_ephemeris = Data_k + Data_j;
strncpy(Data_jk_ephemeris, &Data_k[0], 112); // Join data_j + data_k = Data_jk_ephemeris;
strncat(Data_jk_ephemeris, Data_j, 16); // Data_jk_ephemeris is the input for the function page decoder
//std::cout<<"Data j k ephemeris" << endl << Data_jk_ephemeris << endl; //std::cout<<"Data j k ephemeris" << endl << Data_jk_ephemeris << endl;
page_jk_decoder(Data_jk_ephemeris); // Corresponding to ephemeris_decode.m in matlab code page_jk_decoder(Data_jk_ephemeris.c_str()); // Corresponding to ephemeris_decode.m in matlab code
//internal_flag_even_word_arrived=0;
} }
} /*if(page[0]=='1') */ } /*end if (page_string.at(0)=='1') */
else{ else{
page_Even = page_string.substr (0,114);
strncpy(page_Even, &page[0], 114); //ora che ha memorizzato page even dovrebbe mantenerla per la prossima volta che entro nella funzione //std::cout << "Page even in split page" << std::endl << page_Even << std::endl;
std::cout << "Page even in split page" << std::endl << page_Even << std::endl; std::string tail_Even = page_string.substr (114,6);
strncpy(tail_Even, &page[114], 6); //std::cout << "tail_even_string: " << tail_Even <<std::endl;
if (tail_Even.compare(correct_tail) != 0)
if(strcmp (tail_Even,correct_tail) != 0) std::cout << "Tail even is not correct!" << std::endl;
std::cout << "Tail even is not correct!" << endl; else std::cout<<"Tail even is correct!"<< std::endl;
else std::cout<<"Tail even is correct!"<<endl;
//flag_even_word=1;
} }
@ -532,7 +480,32 @@ Galileo_Ephemeris Galileo_Navigation_Message::get_ephemeris()
{ {
Galileo_Ephemeris ephemeris; Galileo_Ephemeris ephemeris;
//ToDo:: fill the object ephemeris.M0_1 = M0_1; // Mean anomaly at reference time [semi-circles]
ephemeris.delta_n_3 = delta_n_3; // Mean motion difference from computed value [semi-circles/sec]
ephemeris.e_1 = e_1; // Eccentricity
ephemeris.A_1 = A_1; // Square root of the semi-major axis [metres^1/2]
ephemeris.OMEGA_0_2 = OMEGA_0_2;// Longitude of ascending node of orbital plane at weekly epoch [semi-circles]
ephemeris.i_0_2 = i_0_2; // Inclination angle at reference time [semi-circles]
ephemeris.omega_2 = omega_2; // Argument of perigee [semi-circles]
ephemeris.OMEGA_dot_3 = OMEGA_dot_3; // Rate of right ascension [semi-circles/sec]
ephemeris.iDot_2 = iDot_2; // Rate of inclination angle [semi-circles/sec]
ephemeris.C_uc_3 = C_uc_3; // Amplitude of the cosine harmonic correction term to the argument of latitude [radians]
ephemeris.C_us_3 = C_us_3; // Amplitude of the sine harmonic correction term to the argument of latitude [radians]
ephemeris.C_rc_3 = C_rc_3; // Amplitude of the cosine harmonic correction term to the orbit radius [meters]
ephemeris.C_rs_3 = C_rs_3; // Amplitude of the sine harmonic correction term to the orbit radius [meters]
ephemeris.C_ic_4 = C_ic_4; // Amplitude of the cosine harmonic correction term to the angle of inclination [radians]
ephemeris.C_is_4 = C_is_4; // Amplitude of the sine harmonic correction term to the angle of inclination [radians]
ephemeris.t0e_1 = t0e_1; // Ephemeris reference time [s]
/*Clock correction parameters*/
ephemeris.t0c_4 = t0c_4; //Clock correction data reference Time of Week [sec]
ephemeris.af0_4 = af0_4; //SV clock bias correction coefficient [s]
ephemeris.af1_4 = af1_4; //SV clock drift correction coefficient [s/s]
ephemeris.af2_4 = af2_4; //SV clock drift rate correction coefficient [s/s^2]
/*GST*/
ephemeris.WN_5 = WN_5;//Week number
ephemeris.TOW_5 = TOW_5;//Time of Week
return ephemeris; return ephemeris;
} }
@ -540,7 +513,19 @@ Galileo_Ephemeris Galileo_Navigation_Message::get_ephemeris()
Galileo_Iono Galileo_Navigation_Message::get_iono() Galileo_Iono Galileo_Navigation_Message::get_iono()
{ {
Galileo_Iono iono; Galileo_Iono iono;
//ToDo:: fill the object /*Ionospheric correction*/
/*Az*/
iono.ai0_5 = ai0_5; //Effective Ionisation Level 1st order parameter [sfu]
iono.ai1_5 = ai1_5; //Effective Ionisation Level 2st order parameter [sfu/degree]
iono.ai2_5 = ai2_5; //Effective Ionisation Level 3st order parameter [sfu/degree]
/*Ionospheric disturbance flag*/
iono.Region1_flag_5 = Region1_flag_5; // Ionospheric Disturbance Flag for region 1
iono.Region2_flag_5 = Region2_flag_5; // Ionospheric Disturbance Flag for region 2
iono.Region3_flag_5 = Region3_flag_5; // Ionospheric Disturbance Flag for region 3
iono.Region4_flag_5 = Region4_flag_5; // Ionospheric Disturbance Flag for region 4
iono.Region5_flag_5 = Region5_flag_5; // Ionospheric Disturbance Flag for region 5
return iono; return iono;
} }
@ -548,7 +533,20 @@ Galileo_Iono Galileo_Navigation_Message::get_iono()
Galileo_Utc_Model Galileo_Navigation_Message::get_utc_model() Galileo_Utc_Model Galileo_Navigation_Message::get_utc_model()
{ {
Galileo_Utc_Model utc_model; Galileo_Utc_Model utc_model;
//ToDo:: fill the object //Gal_utc_model.valid = flag_utc_model_valid;
/*Word type 6: GST-UTC conversion parameters*/
utc_model.A0_6 = A0_6;
utc_model.A1_6 = A1_6;
utc_model.Delta_tLS_6 = Delta_tLS_6;
utc_model.t0t_6 = t0t_6;
utc_model.WNot_6 = WNot_6;
utc_model.WN_LSF_6 = WN_LSF_6;
utc_model.DN_6 = DN_6;
utc_model.Delta_tLSF_6 = Delta_tLSF_6;
/*GST*/
//utc_model.WN_5 = WN_5; //Week number
//utc_model.TOW_5 = WN_5; //Time of Week
return utc_model; return utc_model;
} }
@ -556,29 +554,76 @@ Galileo_Utc_Model Galileo_Navigation_Message::get_utc_model()
Galileo_Almanac Galileo_Navigation_Message::get_almanac() Galileo_Almanac Galileo_Navigation_Message::get_almanac()
{ {
Galileo_Almanac almanac; Galileo_Almanac almanac;
//ToDo:: fill the object /*Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number*/
almanac.IOD_a_7 = IOD_a_7;
almanac.WN_a_7 = WN_a_7;
almanac.t0a_7 = t0a_7;
almanac.SVID1_7 = SVID1_7;
almanac.DELTA_A_7 = DELTA_A_7;
almanac.e_7 = e_7;
almanac.omega_7 = omega_7;
almanac.delta_i_7 = delta_i_7;
almanac.Omega0_7 = Omega0_7;
almanac.Omega_dot_7 = Omega_dot_7;
almanac.M0_7 = M0_7;
/*Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2)*/
almanac.IOD_a_8 = IOD_a_8;
almanac.af0_8 = af0_8;
almanac.af1_8 = af1_8;
almanac.E5b_HS_8 = E5b_HS_8;
almanac.E1B_HS_8 = E1B_HS_8;
almanac.SVID2_8 = SVID2_8;
almanac.DELTA_A_8 = DELTA_A_8;
almanac.e_8 = e_8;
almanac.omega_8 = omega_8;
almanac.delta_i_8 = delta_i_8;
almanac.Omega0_8 = Omega0_8;
almanac.Omega_dot_8 = Omega_dot_8;
/*Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2)*/
almanac.IOD_a_9 = IOD_a_9;
almanac.WN_a_9 = WN_a_9;
almanac.t0a_9 = t0a_9;
almanac.M0_9 = M0_9;
almanac.af0_9 = af0_9;
almanac.af1_9 = af1_9;
almanac.E5b_HS_9 = E5b_HS_9;
almanac.E1B_HS_9 = E1B_HS_9;
almanac.SVID3_9 = SVID3_9;
almanac.DELTA_A_9 = DELTA_A_9;
almanac.e_9 = e_9;
almanac.omega_9 = omega_9;
almanac.delta_i_9 = delta_i_9;
/*Word type 10: Almanac for SVID3 (2/2)*/
almanac.IOD_a_10 = IOD_a_10;
almanac.Omega0_10 = Omega0_10;
almanac.Omega_dot_10 = Omega_dot_10;
almanac.M0_10 = M0_10;
almanac.af0_10 = af0_10;
almanac.af1_10 = af1_10;
almanac.E5b_HS_10 = E5b_HS_10;
almanac.E1B_HS_10 = E1B_HS_10;
return almanac; return almanac;
} }
int Galileo_Navigation_Message::page_jk_decoder(char *data_jk) int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk)
{ {
std::cout << "--------------------------------------------------------------------------" << endl; std::cout << "--------------------------------------------------------------------------" << std::endl;
std::cout<< "Entered in function Galileo_Navigation_Message::page_jk_decoder(char *data_jk)" << endl << endl; std::cout<< "Entered in function Galileo_Navigation_Message::page_jk_decoder(const char *data_jk)" << std::endl;
int page_number = 0; int page_number = 0;
stringstream ss; std::string data_jk_string = data_jk;
string str; std::bitset<GALILEO_DATA_JK_BITS> data_jk_bits (data_jk_string);
ss << data_jk;
ss >> str;
std::bitset<GALILEO_DATA_JK_BITS> data_jk_bits (str);
//std::cout << "Data_jk_bits (bitset) "<< endl << data_jk_bits << endl; //std::cout << "Data_jk_bits (bitset) "<< endl << data_jk_bits << endl;
page_number = (int)read_navigation_unsigned(data_jk_bits, PAGE_TYPE_bit); page_number = (int)read_navigation_unsigned(data_jk_bits, PAGE_TYPE_bit);
std::cout << "Page number = " << page_number << endl; std::cout << "Page number = " << page_number << std::endl;
switch (page_number) switch (page_number)
{ {
@ -769,9 +814,9 @@ int Galileo_Navigation_Message::page_jk_decoder(char *data_jk)
SVID1_7= (double)read_navigation_unsigned(data_jk_bits, SVID1_7_bit); SVID1_7= (double)read_navigation_unsigned(data_jk_bits, SVID1_7_bit);
std::cout << "SVID1_7= " << SVID1_7 << std::endl; std::cout << "SVID1_7= " << SVID1_7 << std::endl;
Delta_alpha_7= (double)read_navigation_unsigned(data_jk_bits, DELTA_A_7_bit); DELTA_A_7= (double)read_navigation_unsigned(data_jk_bits, DELTA_A_7_bit);
Delta_alpha_7= Delta_alpha_7 * DELTA_A_7_LSB; DELTA_A_7= DELTA_A_7 * DELTA_A_7_LSB;
std::cout << "Delta_alpha_7= " << Delta_alpha_7 << std::endl; std::cout << "DELTA_A_7= " << DELTA_A_7 << std::endl;
e_7= (double)read_navigation_unsigned(data_jk_bits, e_7_bit); e_7= (double)read_navigation_unsigned(data_jk_bits, e_7_bit);
e_7= e_7 * e_7_LSB; e_7= e_7 * e_7_LSB;
@ -960,7 +1005,354 @@ int Galileo_Navigation_Message::page_jk_decoder(char *data_jk)
break; break;
} }
cout<<"--------------------------------------------------------------------------"<<endl;
return page_number; return page_number;
} }
/*Galileo_Ephemeris Galileo_Navigation_Message::get_Galileo_ephemeris()
{
Galileo_Ephemeris Gal_ephemeris;
Gal_ephemeris.M0_1 = M0_1; // Mean anomaly at reference time [semi-circles]
Gal_ephemeris.delta_n_3 = delta_n_3; // Mean motion difference from computed value [semi-circles/sec]
Gal_ephemeris.e_1 = e_1; // Eccentricity
Gal_ephemeris.A_1 = A_1; // Square root of the semi-major axis [metres^1/2]
Gal_ephemeris.OMEGA_0_2 = OMEGA_0_2;// Longitude of ascending node of orbital plane at weekly epoch [semi-circles]
Gal_ephemeris.i_0_2 = i_0_2; // Inclination angle at reference time [semi-circles]
Gal_ephemeris.omega_2 = omega_2; // Argument of perigee [semi-circles]
Gal_ephemeris.OMEGA_dot_3 = OMEGA_dot_3; // Rate of right ascension [semi-circles/sec]
Gal_ephemeris.iDot_2 = iDot_2; // Rate of inclination angle [semi-circles/sec]
Gal_ephemeris.C_uc_3 = C_uc_3; // Amplitude of the cosine harmonic correction term to the argument of latitude [radians]
Gal_ephemeris.C_us_3 = C_us_3; // Amplitude of the sine harmonic correction term to the argument of latitude [radians]
Gal_ephemeris.C_rc_3 = C_rc_3; // Amplitude of the cosine harmonic correction term to the orbit radius [meters]
Gal_ephemeris.C_rs_3 = C_rs_3; // Amplitude of the sine harmonic correction term to the orbit radius [meters]
Gal_ephemeris.C_ic_4 = C_ic_4; // Amplitude of the cosine harmonic correction term to the angle of inclination [radians]
Gal_ephemeris.C_is_4 = C_is_4; // Amplitude of the sine harmonic correction term to the angle of inclination [radians]
Gal_ephemeris.t0e_1 = t0e_1; // Ephemeris reference time [s]
/*Clock correction parameters*
Gal_ephemeris.t0c_4 = t0c_4; //Clock correction data reference Time of Week [sec]
Gal_ephemeris.af0_4 = af0_4; //SV clock bias correction coefficient [s]
Gal_ephemeris.af1_4 = af1_4; //SV clock drift correction coefficient [s/s]
Gal_ephemeris.af2_4 = af2_4; //SV clock drift rate correction coefficient [s/s^2]
/*GST*
Gal_ephemeris.WN_5 = WN_5;//Week number
Gal_ephemeris.TOW_5 = TOW_5;//Time of Week
return Gal_ephemeris;
}*/
/*Galileo_Iono Galileo_Navigation_Message::get_Galileo_Iono()
{
Galileo_Iono Gal_iono;
/*Ionospheric correction
/*Az
Gal_iono.ai0_5 = ai0_5; //Effective Ionisation Level 1st order parameter [sfu]
Gal_iono.ai1_5 = ai1_5; //Effective Ionisation Level 2st order parameter [sfu/degree]
Gal_iono.ai2_5 = ai2_5; //Effective Ionisation Level 3st order parameter [sfu/degree]
/*Ionospheric disturbance flag
Gal_iono.Region1_flag_5 = Region1_flag_5; // Ionospheric Disturbance Flag for region 1
Gal_iono.Region2_flag_5 = Region2_flag_5; // Ionospheric Disturbance Flag for region 2
Gal_iono.Region3_flag_5 = Region3_flag_5; // Ionospheric Disturbance Flag for region 3
Gal_iono.Region4_flag_5 = Region4_flag_5; // Ionospheric Disturbance Flag for region 4
Gal_iono.Region5_flag_5 = Region5_flag_5; // Ionospheric Disturbance Flag for region 5
return Gal_iono;
}*/
/*Galileo_Utc_Model Galileo_Navigation_Message::get_Galileo_utc_model()
{
Galileo_Utc_Model Gal_utc_model;
//Gal_utc_model.valid = flag_utc_model_valid;
/*Word type 6: GST-UTC conversion parameters
Gal_utc_model.A0_6 = A0_6;
Gal_utc_model.A1_6 = A1_6;
Gal_utc_model.Delta_tLS_6 = Delta_tLS_6;
Gal_utc_model.t0t_6 = t0t_6;
Gal_utc_model.WNot_6 = WNot_6;
Gal_utc_model.WN_LSF_6 = WN_LSF_6;
Gal_utc_model.DN_6 = DN_6;
Gal_utc_model.Delta_tLSF_6 = Delta_tLSF_6;
/*GST
//Gal_utc_model.WN_5 = WN_5; //Week number
//Gal_utc_model.TOW_5 = WN_5; //Time of Week
return Gal_utc_model;
}*/
void Galileo_Navigation_Message::satellitePosition(double transmitTime) //when this function in used, the input must be the transmitted time (t) in second computed by Galileo_System_Time (above function)
{
double tk; // Time from ephemeris reference epoch
//double t; // Galileo System Time (ICD, paragraph 5.1.2)
double a; // Semi-major axis
double n; // Corrected mean motion
double n0; // Computed mean motion
double M; // Mean anomaly
double E; //Eccentric Anomaly (to be solved by iteration)
double E_old;
double dE;
double nu; //True anomaly
double phi; //argument of Latitude
double u; // Correct argument of latitude
double r; // Correct radius
double i;
double Omega;
// Find Galileo satellite's position ----------------------------------------------
// Restore semi-major axis
a = A_1*A_1;
// Computed mean motion
n0 = sqrt(GALILEO_GM / (a*a*a));
// Time from ephemeris reference epoch
//tk = check_t(transmitTime - d_Toe); this is tk for GPS; for Galileo it is different
//t = WN_5*86400*7 + TOW_5; //WN_5*86400*7 are the second from the origin of the Galileo time
tk = transmitTime - t0e_1;
// Corrected mean motion
n = n0 + delta_n_3;
// Mean anomaly
M = M0_1 + n * tk;
// Reduce mean anomaly to between 0 and 2pi
M = fmod((M + 2* GALILEO_PI), (2* GALILEO_PI));
// Initial guess of eccentric anomaly
E = M;
// --- Iteratively compute eccentric anomaly ----------------------------
for (int ii = 1; ii<20; ii++)
{
E_old = E;
E = M + e_1 * sin(E);
dE = fmod(E - E_old, 2*GALILEO_PI);
if (fabs(dE) < 1e-12)
{
//Necessary precision is reached, exit from the loop
break;
}
}
// Compute the true anomaly
double tmp_Y = sqrt(1.0 - e_1 * e_1) * sin(E);
double tmp_X = cos(E) - e_1;
nu = atan2(tmp_Y, tmp_X);
// Compute angle phi (argument of Latitude)
phi = nu + omega_2;
// Reduce phi to between 0 and 2*pi rad
phi = fmod((phi), (2*GALILEO_PI));
// Correct argument of latitude
u = phi + C_uc_3 * cos(2*phi) + C_us_3 * sin(2*phi);
// Correct radius
r = a * (1 - e_1*cos(E)) + C_rc_3 * cos(2*phi) + C_rs_3 * sin(2*phi);
// Correct inclination
i = i_0_2 + iDot_2 * tk + C_ic_4 * cos(2*phi) + C_is_4 * sin(2*phi);
// Compute the angle between the ascending node and the Greenwich meridian
Omega = OMEGA_0_2 + (OMEGA_dot_3 - GALILEO_OMEGA_EARTH_DOT)*tk - GALILEO_OMEGA_EARTH_DOT * t0e_1;
// Reduce to between 0 and 2*pi rad
Omega = fmod((Omega + 2*GALILEO_PI), (2*GALILEO_PI));
// --- Compute satellite coordinates in Earth-fixed coordinates
galileo_satpos_X = cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega);
galileo_satpos_Y = cos(u) * r * sin(Omega) + sin(u) * r * cos(i) * cos(Omega); //***********************NOTE: in GALILEO ICD this expression is not correct because it has minus (- sin(u) * r * cos(i) * cos(Omega)) instead of plus
galileo_satpos_Z = sin(u) * r * sin(i);
// Satellite's velocity. Can be useful for Vector Tracking loops
double Omega_dot = OMEGA_dot_3 - GALILEO_OMEGA_EARTH_DOT;
galileo_satvel_X = - Omega_dot * (cos(u) * r + sin(u) * r * cos(i)) + galileo_satpos_X * cos(Omega) - galileo_satpos_Y * cos(i) * sin(Omega);
galileo_satvel_Y = Omega_dot * (cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega)) + galileo_satpos_X * sin(Omega) + galileo_satpos_Y * cos(i) * cos(Omega);
galileo_satvel_Z = galileo_satpos_Y * sin(i);
}
double Galileo_Navigation_Message::Galileo_System_Time(double WN, double TOW){
/* GALIELO SYSTEM TIME, ICD 5.1.2
* input parameter:
* WN: The Week Number is an integer counter that gives the sequential week number
from the origin of the Galileo time. It covers 4096 weeks (about 78 years).
Then the counter is reset to zero to cover additional period modulo 4096
TOW: The Time of Week is defined as the number of seconds that have occurred since
the transition from the previous week. The TOW covers an entire week from 0 to
604799 seconds and is reset to zero at the end of each week
WN and TOW are received in page 5
output:
t: it is the transmitted time in Galileo System Time (expressed in seconds)
The GST start epoch shall be 00:00 UT on Sunday 22nd August 1999 (midnight between 21st and 22nd August).
At the start epoch, GST shall be ahead of UTC by thirteen (13)
leap seconds. Since the next leap second was inserted at 01.01.2006, this implies that
as of 01.01.2006 GST is ahead of UTC by fourteen (14) leap seconds.
The epoch denoted in the navigation messages by TOW and WN
will be measured relative to the leading edge of the first chip of the
first code sequence of the first page symbol. The transmission timing of the navigation
message provided through the TOW is synchronised to each satellites version of Galileo System Time (GST).
*
*/
double t=0;
double sec_in_day = 86400;
double day_in_week = 7;
t = WN*sec_in_day*day_in_week+ TOW; // second from the origin of the Galileo time
return t;
}
double Galileo_Navigation_Message::sv_clock_drift(double transmitTime){
/* Satellite Time Correction Algorithm, ICD 5.1.4
*
*/
double dt;
dt = transmitTime - t0c_4;
Galileo_satClkDrift = af0_4 + af1_4*dt + (af2_4 * dt)*(af2_4 * dt) + Galileo_dtr;
return Galileo_satClkDrift;
}
// compute the relativistic correction term
double Galileo_Navigation_Message::sv_clock_relativistic_term(double transmitTime) //Satellite Time Correction Algorithm, ICD 5.1.4
{
double tk;
double a;
double n;
double n0;
double E;
double E_old;
double dE;
double M;
// Restore semi-major axis
a = A_1*A_1;
n0 = sqrt(GALILEO_GM / (a*a*a));
// Time from ephemeris reference epoch
//tk = check_t(transmitTime - d_Toe); this is tk for GPS; for Galileo it is different
//t = WN_5*86400*7 + TOW_5; //WN_5*86400*7 are the second from the origin of the Galileo time
tk = transmitTime - t0e_1;
// Corrected mean motion
n = n0 + delta_n_3;
// Mean anomaly
M = M0_1 + n * tk;
// Reduce mean anomaly to between 0 and 2pi
M = fmod((M + 2* GALILEO_PI), (2* GALILEO_PI));
// Initial guess of eccentric anomaly
E = M;
// --- Iteratively compute eccentric anomaly ----------------------------
for (int ii = 1; ii<20; ii++)
{
E_old = E;
E = M + e_1 * sin(E);
dE = fmod(E - E_old, 2*GALILEO_PI);
if (fabs(dE) < 1e-12)
{
//Necessary precision is reached, exit from the loop
break;
}
}
// Compute relativistic correction term
Galileo_dtr = GALILEO_F * e_1* A_1 * sin(E);
return Galileo_dtr;
}
double Galileo_Navigation_Message::GST_to_UTC_time(double t_e, int WN)
{
double t_Utc;
double t_Utc_daytime;
double Delta_t_Utc = Delta_tLS_6 + A0_6 + A1_6 * (t_e - t0t_6 + 604800 * (double)(WN - WNot_6));
// Determine if the effectivity time of the leap second event is in the past
int weeksToLeapSecondEvent = WN_LSF_6 - WN;
if ((weeksToLeapSecondEvent) >= 0) // is not in the past
{
//Detect if the effectivity time and user's time is within six hours = 6 * 60 *60 = 21600 s
int secondOfLeapSecondEvent = DN_6 * 24 * 60 * 60;
if (weeksToLeapSecondEvent > 0)
{
t_Utc_daytime = fmod(t_e - Delta_t_Utc, 86400);
}
else //we are in the same week than the leap second event
{
if (abs(t_e - secondOfLeapSecondEvent) > 21600)
{
/* 5.1.7a
* Whenever the leap second adjusted time indicated by the WN_LSF and the DN values
* is not in the past (relative to the user's present time), and the user's
* present time does not fall in the time span which starts at six hours prior
* to the effective time and ends at six hours after the effective time,
* the GST/Utc relationship is given by
*/
t_Utc_daytime = fmod(t_e - Delta_t_Utc, 86400);
}
else
{
/* 5.1.7b
* Whenever the user's current time falls within the time span of six hours
* prior to the leap second adjustment to six hours after the adjustment time, ,
* the effective time is computed according to the following equations:
*/
int W = fmod(t_e - Delta_t_Utc - 43200, 86400) + 43200;
t_Utc_daytime = fmod(W, 86400 + Delta_tLSF_6 - Delta_tLS_6);
//implement something to handle a leap second event!
}
if ( (t_e - secondOfLeapSecondEvent) > 21600)
{
Delta_t_Utc = Delta_tLSF_6 + A0_6 + A1_6 * (t_e - t0t_6 + 604800*(double)(WN - WNot_6));
t_Utc_daytime = fmod(t_e - Delta_t_Utc, 86400);
}
}
}
else // the effectivity time is in the past
{
/* 5.1.7c
* Whenever the leap second adjustment time, as indicated by the WN_LSF and DN values,
* is in the past (relative to the users current time) and the users present time does not
* fall in the time span which starts six hours prior to the leap second adjustment time and
* ends six hours after the adjustment time, the effective time is computed according to
* the following equation:
*/
Delta_t_Utc = Delta_tLSF_6 + A0_6 + A1_6 * (t_e - t0t_6 + 604800 * (double)(WN - WNot_6));
t_Utc_daytime = fmod(t_e - Delta_t_Utc, 86400);
}
double secondsOfWeekBeforeToday = 43200 * floor(t_e / 43200);
t_Utc = secondsOfWeekBeforeToday + t_Utc_daytime;
return t_Utc;
}

View File

@ -50,6 +50,9 @@
#include "galileo_utc_model.h" #include "galileo_utc_model.h"
#include "Galileo_E1.h" #include "Galileo_E1.h"
#include "galileo_ephemeris.h"
#include "galileo_iono.h"
#include "galileo_utc_model.h"
@ -149,7 +152,7 @@ public:
double WN_a_7; double WN_a_7;
double t0a_7; double t0a_7;
int SVID1_7; int SVID1_7;
double Delta_alpha_7; double DELTA_A_7;
double e_7; double e_7;
double omega_7; double omega_7;
double delta_i_7; double delta_i_7;
@ -172,7 +175,6 @@ public:
double Omega_dot_8; double Omega_dot_8;
/*Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2)*/ /*Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2)*/
int IOD_a_9; int IOD_a_9;
double WN_a_9; double WN_a_9;
double t0a_9; double t0a_9;
@ -189,7 +191,6 @@ public:
/*Word type 10: Almanac for SVID3 (2/2) and GST-GPS conversion parameters*/ /*Word type 10: Almanac for SVID3 (2/2) and GST-GPS conversion parameters*/
int IOD_a_10; int IOD_a_10;
double Omega0_10; double Omega0_10;
double Omega_dot_10; double Omega_dot_10;
@ -198,12 +199,11 @@ public:
double af1_10; double af1_10;
double E5b_HS_10; double E5b_HS_10;
double E1B_HS_10; double E1B_HS_10;
double A_0G_10; // GST-GPS conversion
double A_1G_10; double A_0G_10; //constant term of the offset Δt systems
double t_0G_10; double A_1G_10; //rate of change of the offset Δt systems
double WN_0G_10; double t_0G_10; //reference time for GGTO data
double WN_0G_10; //Week Number of GGTO reference
/*Word type 0: I/NAV Spare Word*/ /*Word type 0: I/NAV Spare Word*/
double Time_0; double Time_0;
@ -211,6 +211,20 @@ public:
double TOW_0; double TOW_0;
double Galileo_satClkDrift;
double Galileo_dtr; // relativistic clock correction term
// satellite positions
double galileo_satpos_X; //!< Earth-fixed coordinate x of the satellite [m]. Intersection of the IERS Reference Meridian (IRM) and the plane passing through the origin and normal to the Z-axis.
double galileo_satpos_Y; //!< Earth-fixed coordinate y of the satellite [m]. Completes a right-handed, Earth-Centered, Earth-Fixed orthogonal coordinate system.
double galileo_satpos_Z; //!< Earth-fixed coordinate z of the satellite [m]. The direction of the IERS (International Earth Rotation and Reference Systems Service) Reference Pole (IRP).
// Satellite velocity
double galileo_satvel_X; //!< Earth-fixed velocity coordinate x of the satellite [m]
double galileo_satvel_Y; //!< Earth-fixed velocity coordinate y of the satellite [m]
double galileo_satvel_Z; //!< Earth-fixed velocity coordinate z of the satellite [m]
/* /*
* \brief Takes in input a page (Odd or Even) of 120 bit, split it according ICD 4.3.2.3 and join Data_k with Data_j * \brief Takes in input a page (Odd or Even) of 120 bit, split it according ICD 4.3.2.3 and join Data_k with Data_j
*/ */
@ -218,12 +232,7 @@ public:
/* /*
* \brief Takes in input Data_jk (128 bit) and split it in ephemeris parameters according ICD 4.3.5 * \brief Takes in input Data_jk (128 bit) and split it in ephemeris parameters according ICD 4.3.5
*/ */
int page_jk_decoder(char *data_jk); int page_jk_decoder(const char *data_jk); /* Takes in input Data_jk (128 bit) and split it in ephemeris parameters according ICD 4.3.5*/
/*
* \brief Write doxigen function description here
*/
void reset(); void reset();
@ -266,6 +275,15 @@ public:
*/ */
Galileo_Almanac get_almanac(); Galileo_Almanac get_almanac();
void satellitePosition(double transmitTime);
double Galileo_System_Time(double WN, double TOW); // Galileo System Time (GST), ICD paragraph 5.1.2
double sv_clock_drift(double transmitTime); //Satellite Time Correction Algorithm, ICD 5.1.4
double sv_clock_relativistic_term(double transmitTime); //Satellite Time Correction Algorithm, ICD 5.1.4
double GST_to_UTC_time(double t_e, int WN); //GST-UTC Conversion Algorithm and Parameters
Galileo_Navigation_Message(); Galileo_Navigation_Message();
}; };

View File

@ -42,6 +42,8 @@ Gps_Utc_Model::Gps_Utc_Model()
i_DN = 0; i_DN = 0;
d_DeltaT_LSF = 0; d_DeltaT_LSF = 0;
} }
double Gps_Utc_Model::utc_time(double gpstime_corrected, int i_GPS_week) double Gps_Utc_Model::utc_time(double gpstime_corrected, int i_GPS_week)