mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-07-15 08:23:03 +00:00
Code cleaning
git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@440 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
parent
5b2abb62c2
commit
aa5b531cd3
@ -1,6 +1,6 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file sbas_l1_telemetry_decoder.cc
|
* \file sbas_l1_telemetry_decoder.cc
|
||||||
* \brief Implementation of an adapter of a SBAS telemtry data decoder block
|
* \brief Implementation of an adapter of a SBAS telemetry data decoder block
|
||||||
* to a TelemetryDecoderInterface
|
* to a TelemetryDecoderInterface
|
||||||
* \author Daniel Fehr 2013. daniel.co(at)bluewin.ch
|
* \author Daniel Fehr 2013. daniel.co(at)bluewin.ch
|
||||||
*
|
*
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file sbas_l1_telemetry_decoder.h
|
* \file sbas_l1_telemetry_decoder.h
|
||||||
* \brief Interface of an adapter of a SBAS telemtry data decoder block
|
* \brief Interface of an adapter of a SBAS telemetry data decoder block
|
||||||
* to a TelemetryDecoderInterface
|
* to a TelemetryDecoderInterface
|
||||||
* \author Daniel Fehr 2013. daniel.co(at)bluewin.ch
|
* \author Daniel Fehr 2013. daniel.co(at)bluewin.ch
|
||||||
*
|
*
|
||||||
@ -58,6 +58,9 @@ public:
|
|||||||
return role_;
|
return role_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns "SBAS_L1_Telemetry_Decoder"
|
||||||
|
*/
|
||||||
std::string implementation()
|
std::string implementation()
|
||||||
{
|
{
|
||||||
return "SBAS_L1_Telemetry_Decoder";
|
return "SBAS_L1_Telemetry_Decoder";
|
||||||
|
@ -212,10 +212,11 @@ sbas_l1_telemetry_decoder_cc::sample_aligner::sample_aligner()
|
|||||||
d_iir_par = 0.05;
|
d_iir_par = 0.05;
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
sbas_l1_telemetry_decoder_cc::sample_aligner::~sample_aligner()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
sbas_l1_telemetry_decoder_cc::sample_aligner::~sample_aligner()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::sample_aligner::reset()
|
void sbas_l1_telemetry_decoder_cc::sample_aligner::reset()
|
||||||
{
|
{
|
||||||
@ -225,6 +226,7 @@ void sbas_l1_telemetry_decoder_cc::sample_aligner::reset()
|
|||||||
d_aligned = true;
|
d_aligned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* samples length must be a multiple of two
|
* samples length must be a multiple of two
|
||||||
*/
|
*/
|
||||||
@ -243,15 +245,15 @@ bool sbas_l1_telemetry_decoder_cc::sample_aligner::get_symbols(const std::vector
|
|||||||
// get the next samples
|
// get the next samples
|
||||||
for (int i = 0; i < d_n_smpls_in_history; i++)
|
for (int i = 0; i < d_n_smpls_in_history; i++)
|
||||||
{
|
{
|
||||||
smpls[i] = ((int)i_sym)*sbas_l1_telemetry_decoder_cc::d_samples_per_symbol+i-1 == -1 ? d_past_sample : samples[i_sym*sbas_l1_telemetry_decoder_cc::d_samples_per_symbol+i-1];
|
smpls[i] = ((int)i_sym)*sbas_l1_telemetry_decoder_cc::d_samples_per_symbol + i - 1 == -1 ? d_past_sample : samples[i_sym*sbas_l1_telemetry_decoder_cc::d_samples_per_symbol + i - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the pseudo correlations (IIR method) of the two possible alignments
|
// update the pseudo correlations (IIR method) of the two possible alignments
|
||||||
d_corr_paired = d_iir_par*smpls[1]*smpls[2] + (1-d_iir_par)*d_corr_paired;
|
d_corr_paired = d_iir_par*smpls[1]*smpls[2] + (1 - d_iir_par)*d_corr_paired;
|
||||||
d_corr_shifted = d_iir_par*smpls[0]*smpls[1] + (1-d_iir_par)*d_corr_shifted;
|
d_corr_shifted = d_iir_par*smpls[0]*smpls[1] + (1 - d_iir_par)*d_corr_shifted;
|
||||||
|
|
||||||
// decide which alignment is the correct one
|
// decide which alignment is the correct one
|
||||||
corr_diff = std::abs(d_corr_paired-d_corr_shifted);
|
corr_diff = std::abs(d_corr_paired - d_corr_shifted);
|
||||||
stand_by = d_aligned ? corr_diff < d_corr_paired/2 : corr_diff < d_corr_shifted/2;
|
stand_by = d_aligned ? corr_diff < d_corr_paired/2 : corr_diff < d_corr_shifted/2;
|
||||||
if (!stand_by)
|
if (!stand_by)
|
||||||
{
|
{
|
||||||
@ -259,7 +261,7 @@ bool sbas_l1_telemetry_decoder_cc::sample_aligner::get_symbols(const std::vector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sum the correct pair of samples to a symbol, depending on the current alignment d_align
|
// sum the correct pair of samples to a symbol, depending on the current alignment d_align
|
||||||
sym = smpls[0+int(d_aligned)*2] + smpls[1];
|
sym = smpls[0 + int(d_aligned)*2] + smpls[1];
|
||||||
symbols.push_back(sym);
|
symbols.push_back(sym);
|
||||||
|
|
||||||
// sample alignment debug output
|
// sample alignment debug output
|
||||||
@ -278,13 +280,11 @@ bool sbas_l1_telemetry_decoder_cc::sample_aligner::get_symbols(const std::vector
|
|||||||
double temp;
|
double temp;
|
||||||
temp = samples.back();
|
temp = samples.back();
|
||||||
d_past_sample = (temp);
|
d_past_sample = (temp);
|
||||||
|
|
||||||
return d_aligned;
|
return d_aligned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ### helper class for symbol alignment and viterbi decoding ###
|
// ### helper class for symbol alignment and viterbi decoding ###
|
||||||
|
|
||||||
sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::symbol_aligner_and_decoder()
|
sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::symbol_aligner_and_decoder()
|
||||||
{
|
{
|
||||||
// convolutional code properties
|
// convolutional code properties
|
||||||
@ -298,6 +298,8 @@ sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::symbol_aligner_and_dec
|
|||||||
d_vd2 = new Viterbi_Decoder(g_encoder, d_KK, nn);
|
d_vd2 = new Viterbi_Decoder(g_encoder, d_KK, nn);
|
||||||
d_past_symbol = 0;
|
d_past_symbol = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::~symbol_aligner_and_decoder()
|
sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::~symbol_aligner_and_decoder()
|
||||||
{
|
{
|
||||||
delete d_vd1;
|
delete d_vd1;
|
||||||
@ -311,14 +313,11 @@ void sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::reset()
|
|||||||
d_vd2->reset();
|
d_vd2->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::
|
bool sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::get_bits(const std::vector<double> symbols, std::vector<int> &bits)
|
||||||
get_bits(const std::vector<double> symbols, std::vector<int> &bits)
|
|
||||||
{
|
{
|
||||||
const int traceback_depth = 5*d_KK;
|
const int traceback_depth = 5*d_KK;
|
||||||
|
|
||||||
int nbits_requested = symbols.size()/d_symbols_per_bit;
|
int nbits_requested = symbols.size()/d_symbols_per_bit;
|
||||||
int nbits_decoded;
|
int nbits_decoded;
|
||||||
|
|
||||||
// fill two vectors with the two possible symbol alignments
|
// fill two vectors with the two possible symbol alignments
|
||||||
std::vector<double> symbols_vd1(symbols); // aligned symbol vector -> copy input symbol vector
|
std::vector<double> symbols_vd1(symbols); // aligned symbol vector -> copy input symbol vector
|
||||||
std::vector<double> symbols_vd2; // shifted symbol vector -> add past sample in front of input vector
|
std::vector<double> symbols_vd2; // shifted symbol vector -> add past sample in front of input vector
|
||||||
@ -327,15 +326,12 @@ get_bits(const std::vector<double> symbols, std::vector<int> &bits)
|
|||||||
{
|
{
|
||||||
symbols_vd2.push_back(*symbol_it);
|
symbols_vd2.push_back(*symbol_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
// arrays for decoded bits
|
// arrays for decoded bits
|
||||||
int * bits_vd1 = new int[nbits_requested];
|
int * bits_vd1 = new int[nbits_requested];
|
||||||
int * bits_vd2 = new int[nbits_requested];
|
int * bits_vd2 = new int[nbits_requested];
|
||||||
|
|
||||||
// decode
|
// decode
|
||||||
float metric_vd1 = d_vd1->decode_continuous(symbols_vd1.data(), traceback_depth, bits_vd1, nbits_requested, nbits_decoded);
|
float metric_vd1 = d_vd1->decode_continuous(symbols_vd1.data(), traceback_depth, bits_vd1, nbits_requested, nbits_decoded);
|
||||||
float metric_vd2 = d_vd2->decode_continuous(symbols_vd2.data(), traceback_depth, bits_vd2, nbits_requested, nbits_decoded);
|
float metric_vd2 = d_vd2->decode_continuous(symbols_vd2.data(), traceback_depth, bits_vd2, nbits_requested, nbits_decoded);
|
||||||
|
|
||||||
// choose the bits with the better metric
|
// choose the bits with the better metric
|
||||||
for (int i = 0; i<nbits_decoded; i++)
|
for (int i = 0; i<nbits_decoded; i++)
|
||||||
{
|
{
|
||||||
@ -348,36 +344,28 @@ get_bits(const std::vector<double> symbols, std::vector<int> &bits)
|
|||||||
bits.push_back(bits_vd2[i]);
|
bits.push_back(bits_vd2[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d_past_symbol = symbols.back();
|
d_past_symbol = symbols.back();
|
||||||
|
|
||||||
delete[] bits_vd1;
|
delete[] bits_vd1;
|
||||||
delete[] bits_vd2;
|
delete[] bits_vd2;
|
||||||
|
|
||||||
return metric_vd1 > metric_vd2;
|
return metric_vd1 > metric_vd2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ### helper class for detecting the preamble and collect the corresponding message candidates ###
|
// ### helper class for detecting the preamble and collect the corresponding message candidates ###
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::frame_detector::reset()
|
void sbas_l1_telemetry_decoder_cc::frame_detector::reset()
|
||||||
{
|
{
|
||||||
d_buffer.clear();
|
d_buffer.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::frame_detector::
|
|
||||||
get_frame_candidates(const std::vector<int> bits, std::vector<std::pair<int,std::vector<int>>> &msg_candidates)
|
void sbas_l1_telemetry_decoder_cc::frame_detector::get_frame_candidates(const std::vector<int> bits, std::vector<std::pair<int,std::vector<int>>> &msg_candidates)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
unsigned int sbas_msg_length = 250;
|
unsigned int sbas_msg_length = 250;
|
||||||
std::vector<std::vector<int>> preambles = {{0, 1, 0, 1, 0, 0, 1 ,1},
|
std::vector<std::vector<int>> preambles = {{0, 1, 0, 1, 0, 0, 1 ,1},
|
||||||
{1, 0, 0, 1, 1, 0, 1, 0},
|
{1, 0, 0, 1, 1, 0, 1, 0},
|
||||||
{1, 1, 0, 0, 0, 1, 1, 0}};
|
{1, 1, 0, 0, 0, 1, 1, 0}};
|
||||||
|
|
||||||
VLOG(FLOW) << "get_frame_candidates(): " << "d_buffer.size()=" << d_buffer.size() << "\tbits.size()=" << bits.size();
|
VLOG(FLOW) << "get_frame_candidates(): " << "d_buffer.size()=" << d_buffer.size() << "\tbits.size()=" << bits.size();
|
||||||
|
|
||||||
|
|
||||||
ss << "copy bits ";
|
ss << "copy bits ";
|
||||||
int count = 0;
|
int count = 0;
|
||||||
// copy new bits into the working buffer
|
// copy new bits into the working buffer
|
||||||
@ -388,7 +376,6 @@ get_frame_candidates(const std::vector<int> bits, std::vector<std::pair<int,std:
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
VLOG(SAMP_SYNC) << ss.str() << " into working buffer (" << count << " bits)";
|
VLOG(SAMP_SYNC) << ss.str() << " into working buffer (" << count << " bits)";
|
||||||
|
|
||||||
int relative_preamble_start = 0;
|
int relative_preamble_start = 0;
|
||||||
while(d_buffer.size() >= sbas_msg_length)
|
while(d_buffer.size() >= sbas_msg_length)
|
||||||
{
|
{
|
||||||
@ -400,22 +387,21 @@ get_frame_candidates(const std::vector<int> bits, std::vector<std::pair<int,std:
|
|||||||
// compare the buffer bits with the preamble bits
|
// compare the buffer bits with the preamble bits
|
||||||
for (std::vector<int>::iterator preample_bit_it = preample_it->begin(); preample_bit_it < preample_it->end(); ++preample_bit_it)
|
for (std::vector<int>::iterator preample_bit_it = preample_it->begin(); preample_bit_it < preample_it->end(); ++preample_bit_it)
|
||||||
{
|
{
|
||||||
preamble_detected = *preample_bit_it == d_buffer[preample_bit_it-preample_it->begin()] ? preamble_detected : false ;
|
preamble_detected = *preample_bit_it == d_buffer[preample_bit_it - preample_it->begin()] ? preamble_detected : false ;
|
||||||
inv_preamble_detected = *preample_bit_it != d_buffer[preample_bit_it-preample_it->begin()] ? inv_preamble_detected : false ;
|
inv_preamble_detected = *preample_bit_it != d_buffer[preample_bit_it - preample_it->begin()] ? inv_preamble_detected : false ;
|
||||||
}
|
}
|
||||||
if (preamble_detected || inv_preamble_detected)
|
if (preamble_detected || inv_preamble_detected)
|
||||||
{
|
{
|
||||||
// copy candidate
|
// copy candidate
|
||||||
std::vector<int> candidate;
|
std::vector<int> candidate;
|
||||||
std::copy(d_buffer.begin(), d_buffer.begin()+sbas_msg_length, std::back_inserter(candidate));
|
std::copy(d_buffer.begin(), d_buffer.begin() + sbas_msg_length, std::back_inserter(candidate));
|
||||||
if(inv_preamble_detected)
|
if(inv_preamble_detected)
|
||||||
{
|
{
|
||||||
// invert bits
|
// invert bits
|
||||||
for (std::vector<int>::iterator candidate_bit_it = candidate.begin(); candidate_bit_it != candidate.end(); candidate_bit_it++)
|
for (std::vector<int>::iterator candidate_bit_it = candidate.begin(); candidate_bit_it != candidate.end(); candidate_bit_it++)
|
||||||
*candidate_bit_it = *candidate_bit_it == 0 ? 1:0;
|
*candidate_bit_it = *candidate_bit_it == 0 ? 1:0;
|
||||||
}
|
}
|
||||||
msg_candidates.push_back(std::pair<int,std::vector<int>>(relative_preamble_start,candidate));
|
msg_candidates.push_back(std::pair<int,std::vector<int>>(relative_preamble_start, candidate));
|
||||||
|
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss << "preamble " << preample_it - preambles.begin() << (inv_preamble_detected?" inverted":" normal") << " detected! candidate=";
|
ss << "preamble " << preample_it - preambles.begin() << (inv_preamble_detected?" inverted":" normal") << " detected! candidate=";
|
||||||
for (std::vector<int>::iterator bit_it = candidate.begin(); bit_it < candidate.end(); ++bit_it)
|
for (std::vector<int>::iterator bit_it = candidate.begin(); bit_it < candidate.end(); ++bit_it)
|
||||||
@ -424,10 +410,8 @@ get_frame_candidates(const std::vector<int> bits, std::vector<std::pair<int,std:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
relative_preamble_start++;
|
relative_preamble_start++;
|
||||||
|
|
||||||
// remove bit in front
|
// remove bit in front
|
||||||
d_buffer.pop_front();
|
d_buffer.pop_front();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,28 +424,22 @@ void sbas_l1_telemetry_decoder_cc::crc_verifier::reset()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::crc_verifier::
|
void sbas_l1_telemetry_decoder_cc::crc_verifier::get_valid_frames(const std::vector<msg_candiate_int_t> msg_candidates, std::vector<msg_candiate_char_t> &valid_msgs)
|
||||||
get_valid_frames(const std::vector<msg_candiate_int_t> msg_candidates, std::vector<msg_candiate_char_t> &valid_msgs)
|
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
VLOG(FLOW) << "get_valid_frames(): " << "msg_candidates.size()=" << msg_candidates.size();
|
VLOG(FLOW) << "get_valid_frames(): " << "msg_candidates.size()=" << msg_candidates.size();
|
||||||
|
|
||||||
// for each candidate
|
// for each candidate
|
||||||
for (std::vector<msg_candiate_int_t>::const_iterator candidate_it = msg_candidates.begin(); candidate_it < msg_candidates.end(); ++candidate_it)
|
for (std::vector<msg_candiate_int_t>::const_iterator candidate_it = msg_candidates.begin(); candidate_it < msg_candidates.end(); ++candidate_it)
|
||||||
{
|
{
|
||||||
// convert to bytes
|
// convert to bytes
|
||||||
std::vector<unsigned char> candidate_bytes;
|
std::vector<unsigned char> candidate_bytes;
|
||||||
zerropad_back_and_convert_to_bytes(candidate_it->second, candidate_bytes);
|
zerropad_back_and_convert_to_bytes(candidate_it->second, candidate_bytes);
|
||||||
|
|
||||||
// verify CRC
|
// verify CRC
|
||||||
d_checksum_agent.reset(0);
|
d_checksum_agent.reset(0);
|
||||||
d_checksum_agent.process_bytes(candidate_bytes.data(), candidate_bytes.size());
|
d_checksum_agent.process_bytes(candidate_bytes.data(), candidate_bytes.size());
|
||||||
unsigned int crc = d_checksum_agent.checksum();
|
unsigned int crc = d_checksum_agent.checksum();
|
||||||
|
|
||||||
VLOG(SAMP_SYNC) << "candidate " << candidate_it - msg_candidates.begin() << ": final crc remainder= " << std::hex << crc
|
VLOG(SAMP_SYNC) << "candidate " << candidate_it - msg_candidates.begin() << ": final crc remainder= " << std::hex << crc
|
||||||
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
||||||
|
|
||||||
// the final remainder must be zero for a valid message, because the CRC is done over the received CRC value
|
// the final remainder must be zero for a valid message, because the CRC is done over the received CRC value
|
||||||
if (crc == 0)
|
if (crc == 0)
|
||||||
{
|
{
|
||||||
@ -481,25 +459,23 @@ get_valid_frames(const std::vector<msg_candiate_int_t> msg_candidates, std::vect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::crc_verifier::
|
|
||||||
zerropad_back_and_convert_to_bytes(const std::vector<int> msg_candidate, std::vector<unsigned char> &bytes)
|
|
||||||
|
|
||||||
|
|
||||||
|
void sbas_l1_telemetry_decoder_cc::crc_verifier::zerropad_back_and_convert_to_bytes(const std::vector<int> msg_candidate, std::vector<unsigned char> &bytes)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
const size_t bits_per_byte = 8;
|
const size_t bits_per_byte = 8;
|
||||||
unsigned char byte = 0;
|
unsigned char byte = 0;
|
||||||
|
|
||||||
VLOG(LMORE) << "zerropad_back_and_convert_to_bytes():" << byte;
|
VLOG(LMORE) << "zerropad_back_and_convert_to_bytes():" << byte;
|
||||||
|
|
||||||
for (std::vector<int>::const_iterator candidate_bit_it = msg_candidate.begin(); candidate_bit_it < msg_candidate.end(); ++candidate_bit_it)
|
for (std::vector<int>::const_iterator candidate_bit_it = msg_candidate.begin(); candidate_bit_it < msg_candidate.end(); ++candidate_bit_it)
|
||||||
{
|
{
|
||||||
int idx_bit = candidate_bit_it - msg_candidate.begin();
|
int idx_bit = candidate_bit_it - msg_candidate.begin();
|
||||||
int bit_pos_in_current_byte = (bits_per_byte-1)-(idx_bit % bits_per_byte);
|
int bit_pos_in_current_byte = (bits_per_byte - 1) - (idx_bit % bits_per_byte);
|
||||||
|
|
||||||
byte |= (unsigned char)(*candidate_bit_it) << bit_pos_in_current_byte;
|
byte |= (unsigned char)(*candidate_bit_it) << bit_pos_in_current_byte;
|
||||||
|
|
||||||
ss << *candidate_bit_it;
|
ss << *candidate_bit_it;
|
||||||
|
if (idx_bit % bits_per_byte == bits_per_byte - 1)
|
||||||
if (idx_bit % bits_per_byte == bits_per_byte-1)
|
|
||||||
{
|
{
|
||||||
bytes.push_back(byte);
|
bytes.push_back(byte);
|
||||||
VLOG(LMORE) << ss.str() << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)byte; ss.str("");
|
VLOG(LMORE) << ss.str() << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)byte; ss.str("");
|
||||||
@ -511,52 +487,51 @@ zerropad_back_and_convert_to_bytes(const std::vector<int> msg_candidate, std::ve
|
|||||||
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::crc_verifier::
|
|
||||||
zerropad_front_and_convert_to_bytes(const std::vector<int> msg_candidate, std::vector<unsigned char> &bytes)
|
|
||||||
|
void sbas_l1_telemetry_decoder_cc::crc_verifier::zerropad_front_and_convert_to_bytes(const std::vector<int> msg_candidate, std::vector<unsigned char> &bytes)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
const size_t bits_per_byte = 8;
|
const size_t bits_per_byte = 8;
|
||||||
unsigned char byte = 0;
|
unsigned char byte = 0;
|
||||||
int idx_bit = 6; // insert 6 zeros at the front to fit the 250bits into a multiple of bytes
|
int idx_bit = 6; // insert 6 zeros at the front to fit the 250bits into a multiple of bytes
|
||||||
|
|
||||||
VLOG(LMORE) << "zerropad_front_and_convert_to_bytes():" << byte;
|
VLOG(LMORE) << "zerropad_front_and_convert_to_bytes():" << byte;
|
||||||
|
|
||||||
for (std::vector<int>::const_iterator candidate_bit_it = msg_candidate.begin(); candidate_bit_it < msg_candidate.end(); ++candidate_bit_it)
|
for (std::vector<int>::const_iterator candidate_bit_it = msg_candidate.begin(); candidate_bit_it < msg_candidate.end(); ++candidate_bit_it)
|
||||||
{
|
{
|
||||||
int bit_pos_in_current_byte = (bits_per_byte-1)-(idx_bit % bits_per_byte);
|
int bit_pos_in_current_byte = (bits_per_byte - 1) - (idx_bit % bits_per_byte);
|
||||||
|
|
||||||
byte |= (unsigned char)(*candidate_bit_it) << bit_pos_in_current_byte;
|
byte |= (unsigned char)(*candidate_bit_it) << bit_pos_in_current_byte;
|
||||||
|
|
||||||
ss << *candidate_bit_it;
|
ss << *candidate_bit_it;
|
||||||
|
if (idx_bit % bits_per_byte == bits_per_byte - 1)
|
||||||
if (idx_bit % bits_per_byte == bits_per_byte-1)
|
|
||||||
{
|
{
|
||||||
bytes.push_back(byte);
|
bytes.push_back(byte);
|
||||||
VLOG(LMORE) << ss.str() << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)byte; ss.str("");
|
VLOG(LMORE) << ss.str() << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)byte; ss.str("");
|
||||||
byte = 0;
|
byte = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
idx_bit++;
|
idx_bit++;
|
||||||
}
|
}
|
||||||
VLOG(LMORE) << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)byte
|
VLOG(LMORE) << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)byte
|
||||||
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::set_raw_msg_queue(concurrent_queue<Sbas_Raw_Msg> *raw_msg_queue)
|
void sbas_l1_telemetry_decoder_cc::set_raw_msg_queue(concurrent_queue<Sbas_Raw_Msg> *raw_msg_queue)
|
||||||
{
|
{
|
||||||
sbas_telemetry_data.set_raw_msg_queue(raw_msg_queue);
|
sbas_telemetry_data.set_raw_msg_queue(raw_msg_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::set_iono_queue(concurrent_queue<Sbas_Ionosphere_Correction> *iono_queue)
|
void sbas_l1_telemetry_decoder_cc::set_iono_queue(concurrent_queue<Sbas_Ionosphere_Correction> *iono_queue)
|
||||||
{
|
{
|
||||||
sbas_telemetry_data.set_iono_queue(iono_queue);
|
sbas_telemetry_data.set_iono_queue(iono_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::set_sat_corr_queue(concurrent_queue<Sbas_Satellite_Correction> *sat_corr_queue)
|
void sbas_l1_telemetry_decoder_cc::set_sat_corr_queue(concurrent_queue<Sbas_Satellite_Correction> *sat_corr_queue)
|
||||||
{
|
{
|
||||||
sbas_telemetry_data.set_sat_corr_queue(sat_corr_queue);
|
sbas_telemetry_data.set_sat_corr_queue(sat_corr_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::set_ephemeris_queue(concurrent_queue<Sbas_Ephemeris> *ephemeris_queue)
|
void sbas_l1_telemetry_decoder_cc::set_ephemeris_queue(concurrent_queue<Sbas_Ephemeris> *ephemeris_queue)
|
||||||
{
|
{
|
||||||
sbas_telemetry_data.set_ephemeris_queue(ephemeris_queue);
|
sbas_telemetry_data.set_ephemeris_queue(ephemeris_queue);
|
||||||
|
@ -103,15 +103,12 @@ private:
|
|||||||
public:
|
public:
|
||||||
sample_aligner();
|
sample_aligner();
|
||||||
~sample_aligner();
|
~sample_aligner();
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* samples length must be a multiple of two
|
* samples length must be a multiple of two
|
||||||
* for block operation the
|
* for block operation the
|
||||||
*/
|
*/
|
||||||
bool get_symbols(const std::vector<double> samples, std::vector<double> &symbols);
|
bool get_symbols(const std::vector<double> samples, std::vector<double> &symbols);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int d_n_smpls_in_history ;
|
int d_n_smpls_in_history ;
|
||||||
double d_iir_par;
|
double d_iir_par;
|
||||||
@ -128,11 +125,8 @@ private:
|
|||||||
public:
|
public:
|
||||||
symbol_aligner_and_decoder();
|
symbol_aligner_and_decoder();
|
||||||
~symbol_aligner_and_decoder();
|
~symbol_aligner_and_decoder();
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
bool get_bits(const std::vector<double> symbols, std::vector<int> &bits);
|
bool get_bits(const std::vector<double> symbols, std::vector<int> &bits);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int d_KK;
|
int d_KK;
|
||||||
Viterbi_Decoder * d_vd1;
|
Viterbi_Decoder * d_vd1;
|
||||||
@ -141,33 +135,32 @@ private:
|
|||||||
|
|
||||||
} d_symbol_aligner_and_decoder;
|
} d_symbol_aligner_and_decoder;
|
||||||
|
|
||||||
|
|
||||||
// helper class for detecting the preamble and collect the corresponding message candidates
|
// helper class for detecting the preamble and collect the corresponding message candidates
|
||||||
class frame_detector
|
class frame_detector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void reset();
|
void reset();
|
||||||
void get_frame_candidates(const std::vector<int> bits, std::vector<std::pair<int, std::vector<int>>> &msg_candidates);
|
void get_frame_candidates(const std::vector<int> bits, std::vector<std::pair<int, std::vector<int>>> &msg_candidates);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::deque<int> d_buffer;
|
std::deque<int> d_buffer;
|
||||||
|
|
||||||
} d_frame_detector;
|
} d_frame_detector;
|
||||||
|
|
||||||
|
|
||||||
// helper class for checking the CRC of the message candidates
|
// helper class for checking the CRC of the message candidates
|
||||||
class crc_verifier
|
class crc_verifier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void reset();
|
void reset();
|
||||||
void get_valid_frames(const std::vector<msg_candiate_int_t> msg_candidates, std::vector<msg_candiate_char_t> &valid_msgs);
|
void get_valid_frames(const std::vector<msg_candiate_int_t> msg_candidates, std::vector<msg_candiate_char_t> &valid_msgs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef boost::crc_optimal<24, 0x1864CFBu, 0x0, 0x0, false, false> crc_24_q_type;
|
typedef boost::crc_optimal<24, 0x1864CFBu, 0x0, 0x0, false, false> crc_24_q_type;
|
||||||
crc_24_q_type d_checksum_agent;
|
crc_24_q_type d_checksum_agent;
|
||||||
void zerropad_front_and_convert_to_bytes(const std::vector<int> msg_candidate, std::vector<unsigned char> &bytes);
|
void zerropad_front_and_convert_to_bytes(const std::vector<int> msg_candidate, std::vector<unsigned char> &bytes);
|
||||||
void zerropad_back_and_convert_to_bytes(const std::vector<int> msg_candidate, std::vector<unsigned char> &bytes);
|
void zerropad_back_and_convert_to_bytes(const std::vector<int> msg_candidate, std::vector<unsigned char> &bytes);
|
||||||
|
|
||||||
} d_crc_verifier;
|
} d_crc_verifier;
|
||||||
|
|
||||||
|
|
||||||
Sbas_Telemetry_Data sbas_telemetry_data;
|
Sbas_Telemetry_Data sbas_telemetry_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* \file sbas_ephemeris.cc
|
* \file sbas_ephemeris.cc
|
||||||
* \brief Interface of a SBAS REFERENCE LOCATION storage
|
* \brief Implementation of a SBAS REFERENCE LOCATION storage
|
||||||
*
|
*
|
||||||
* \author Daniel Fehr, 2013. daniel.co(at)bluewin.ch
|
* \author Daniel Fehr, 2013. daniel.co(at)bluewin.ch
|
||||||
*
|
*
|
||||||
@ -33,7 +33,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "sbas_ephemeris.h"
|
#include "sbas_ephemeris.h"
|
||||||
|
|
||||||
void Sbas_Ephemeris::print(std::ostream &out)
|
void Sbas_Ephemeris::print(std::ostream &out)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* \file sbas_ephemeris.h
|
* \file sbas_ephemeris.h
|
||||||
* \brief Implementation of a SBAS REFERENCE LOCATION storage
|
* \brief Interface of a SBAS REFERENCE LOCATION storage
|
||||||
*
|
*
|
||||||
* \author Daniel Fehr, 2013. daniel.co(at)bluewin.ch
|
* \author Daniel Fehr, 2013. daniel.co(at)bluewin.ch
|
||||||
*
|
*
|
||||||
@ -33,23 +33,26 @@
|
|||||||
#ifndef GNSS_SDR_SBAS_EPHEMERIS_H_
|
#ifndef GNSS_SDR_SBAS_EPHEMERIS_H_
|
||||||
#define GNSS_SDR_SBAS_EPHEMERIS_H_
|
#define GNSS_SDR_SBAS_EPHEMERIS_H_
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief This class stores SBAS SV ephemeris data
|
||||||
|
*
|
||||||
|
*/
|
||||||
class Sbas_Ephemeris
|
class Sbas_Ephemeris
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void print(std::ostream &out);
|
void print(std::ostream &out);
|
||||||
int i_prn; // PRN number */
|
int i_prn; //!< PRN number
|
||||||
//gtime_t t0; // reference epoch time (GPST)
|
//gtime_t t0; //!< reference epoch time (GPST)
|
||||||
int i_t0;
|
int i_t0;
|
||||||
//gtime_t tof; // time of message frame (GPST)
|
//gtime_t tof; // time of message frame (GPST)
|
||||||
double d_tof;
|
double d_tof;
|
||||||
int i_sv_ura; // SV accuracy (URA index), not standardized
|
int i_sv_ura; //!< SV accuracy (URA index), not standardized
|
||||||
bool b_sv_do_not_use; // health status (false:don't use / true:usable)
|
bool b_sv_do_not_use; //!< health status (false:do not use / true:usable)
|
||||||
double d_pos[3]; // satellite position (m) (ecef)
|
double d_pos[3]; //!< satellite position (m) (ECEF)
|
||||||
double d_vel[3]; // satellite velocity (m/s) (ecef)
|
double d_vel[3]; //!< satellite velocity (m/s) (ECEF)
|
||||||
double d_acc[3]; // satellite acceleration (m/s^2) (ecef)
|
double d_acc[3]; //!< satellite acceleration (m/s^2) (ECEF)
|
||||||
double d_af0; // satellite clock-offset (s)
|
double d_af0; //!< satellite clock-offset (s)
|
||||||
double d_af1; // satellite drift (s/s)
|
double d_af1; //!< satellite drift (s/s)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,11 +92,6 @@ bool Sbas_Ionosphere_Correction::apply(double sample_stamp, double latitude_d, d
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define PI 3.1415926535897932 /* pi */
|
|
||||||
#define D2R (PI/180.0) /* deg to rad */
|
|
||||||
#define R2D (180.0/PI) /* rad to deg */
|
|
||||||
#define MAXBAND 10 /* max SBAS band of IGP */
|
|
||||||
#define RE_WGS84 6378137.0 /* earth semimajor axis (WGS84) (m) */
|
|
||||||
|
|
||||||
/* geometric distance ----------------------------------------------------------
|
/* geometric distance ----------------------------------------------------------
|
||||||
* compute geometric distance and receiver-to-satellite unit vector
|
* compute geometric distance and receiver-to-satellite unit vector
|
||||||
@ -139,9 +134,9 @@ void Sbas_Ionosphere_Correction::matmul(const char *tr, int n, int k, int m, dou
|
|||||||
const double *A, const double *B, double beta, double *C)
|
const double *A, const double *B, double beta, double *C)
|
||||||
{
|
{
|
||||||
double d;
|
double d;
|
||||||
int i, j, x, f = tr[0]=='N'?(tr[1]=='N'?1:2):(tr[1]=='N'?3:4);
|
int i, j, x, f = tr[0]=='N' ? (tr[1]=='N'?1:2):(tr[1]=='N'?3:4);
|
||||||
|
|
||||||
for (i=0; i<n; i++) for (j=0;j<k;j++)
|
for (i=0; i<n; i++) for (j=0; j<k; j++)
|
||||||
{
|
{
|
||||||
d = 0.0;
|
d = 0.0;
|
||||||
switch (f)
|
switch (f)
|
||||||
@ -151,7 +146,14 @@ void Sbas_Ionosphere_Correction::matmul(const char *tr, int n, int k, int m, dou
|
|||||||
case 3: for (x=0; x<m; x++) d += A[x+i*m]*B[x+j*m]; break;
|
case 3: for (x=0; x<m; x++) d += A[x+i*m]*B[x+j*m]; break;
|
||||||
case 4: for (x=0; x<m; x++) d += A[x+i*m]*B[j+x*k]; break;
|
case 4: for (x=0; x<m; x++) d += A[x+i*m]*B[j+x*k]; break;
|
||||||
}
|
}
|
||||||
if (beta==0.0) C[i+j*n] = alpha*d; else C[i+j*n] = alpha*d + beta*C[i+j*n];
|
if (beta == 0.0)
|
||||||
|
{
|
||||||
|
C[i+j*n] = alpha*d;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
C[i+j*n] = alpha*d + beta*C[i+j*n];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,20 +163,19 @@ void Sbas_Ionosphere_Correction::matmul(const char *tr, int n, int k, int m, dou
|
|||||||
* args : double *pos I geodetic position {lat,lon} (rad)
|
* args : double *pos I geodetic position {lat,lon} (rad)
|
||||||
* double *E O ecef to local coord transformation matrix (3x3)
|
* double *E O ecef to local coord transformation matrix (3x3)
|
||||||
* return : none
|
* return : none
|
||||||
* notes : matirix stored by column-major order (fortran convention)
|
* notes : matrix stored by column-major order (fortran convention)
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
void Sbas_Ionosphere_Correction::xyz2enu(const double *pos, double *E)
|
void Sbas_Ionosphere_Correction::xyz2enu(const double *pos, double *E)
|
||||||
{
|
{
|
||||||
double sinp = sin(pos[0]), cosp = cos(pos[0]), sinl = sin(pos[1]), cosl = cos(pos[1]);
|
double sinp = sin(pos[0]), cosp = cos(pos[0]), sinl = sin(pos[1]), cosl = cos(pos[1]);
|
||||||
|
|
||||||
E[0] = -sinl; E[3] = cosl; E[6] = 0.0;
|
E[0] = -sinl; E[3] = cosl; E[6] = 0.0;
|
||||||
E[1] = -sinp*cosl; E[4] = -sinp*sinl; E[7] = cosp;
|
E[1] = -sinp*cosl; E[4] = -sinp*sinl; E[7] = cosp;
|
||||||
E[2] = cosp*cosl; E[5] = cosp*sinl; E[8] = sinp;
|
E[2] = cosp*cosl; E[5] = cosp*sinl; E[8] = sinp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* transform ecef vector to local tangental coordinate -------------------------
|
/* transform ecef vector to local tangential coordinate -------------------------
|
||||||
* transform ecef vector to local tangental coordinate
|
* transform ecef vector to local tangential coordinate
|
||||||
* args : double *pos I geodetic position {lat,lon} (rad)
|
* args : double *pos I geodetic position {lat,lon} (rad)
|
||||||
* double *r I vector in ecef coordinate {x,y,z}
|
* double *r I vector in ecef coordinate {x,y,z}
|
||||||
* double *e O vector in local tangental coordinate {e,n,u}
|
* double *e O vector in local tangental coordinate {e,n,u}
|
||||||
@ -183,13 +184,19 @@ void Sbas_Ionosphere_Correction::xyz2enu(const double *pos, double *E)
|
|||||||
void Sbas_Ionosphere_Correction::ecef2enu(const double *pos, const double *r, double *e)
|
void Sbas_Ionosphere_Correction::ecef2enu(const double *pos, const double *r, double *e)
|
||||||
{
|
{
|
||||||
double E[9];
|
double E[9];
|
||||||
|
|
||||||
xyz2enu(pos, E);
|
xyz2enu(pos, E);
|
||||||
matmul("NN", 3, 1, 3, 1.0, E, r, 0.0, e);
|
matmul("NN", 3, 1, 3, 1.0, E, r, 0.0, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const double PI = 3.1415926535897932; /* pi */
|
||||||
|
//const double D2R = (PI/180.0); /* deg to rad */
|
||||||
|
//const double R2D = (180.0/PI); /* rad to deg */
|
||||||
|
//const double MAXBAND = 10; /* max SBAS band of IGP */
|
||||||
|
//const double RE_WGS84 = 6378137.0; /* earth semimajor axis (WGS84) (m) */
|
||||||
|
|
||||||
|
|
||||||
/* satellite azimuth/elevation angle -------------------------------------------
|
/* satellite azimuth/elevation angle -------------------------------------------
|
||||||
* compute satellite azimuth/elevation angle
|
* compute satellite azimuth/elevation angle
|
||||||
* args : double *pos I geodetic position {lat,lon,h} (rad,m)
|
* args : double *pos I geodetic position {lat,lon,h} (rad,m)
|
||||||
@ -200,19 +207,21 @@ void Sbas_Ionosphere_Correction::ecef2enu(const double *pos, const double *r, do
|
|||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
double Sbas_Ionosphere_Correction::satazel(const double *pos, const double *e, double *azel)
|
double Sbas_Ionosphere_Correction::satazel(const double *pos, const double *e, double *azel)
|
||||||
{
|
{
|
||||||
double az = 0.0, el=PI/2.0, enu[3];
|
const double RE_WGS84 = 6378137.0; /* earth semimajor axis (WGS84) (m) */
|
||||||
|
|
||||||
|
double az = 0.0, el = PI/2.0, enu[3];
|
||||||
|
|
||||||
if (pos[2] > -RE_WGS84)
|
if (pos[2] > -RE_WGS84)
|
||||||
{
|
{
|
||||||
ecef2enu(pos,e,enu);
|
ecef2enu(pos, e, enu);
|
||||||
az = dot(enu,enu,2) < 1E-12?0.0:atan2(enu[0], enu[1]);
|
az = dot(enu ,enu, 2) < 1E-12 ? 0.0:atan2(enu[0], enu[1]);
|
||||||
if (az<0.0) az += 2*PI;
|
if (az < 0.0) az += 2*PI;
|
||||||
el = asin(enu[2]);
|
el = asin(enu[2]);
|
||||||
}
|
}
|
||||||
if (azel)
|
if (azel)
|
||||||
{
|
{
|
||||||
azel[0]=az;
|
azel[0] = az;
|
||||||
azel[1]=el;
|
azel[1] = el;
|
||||||
}
|
}
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
@ -242,6 +251,8 @@ double Sbas_Ionosphere_Correction::ionppp(const double *pos, const double *azel,
|
|||||||
double re, double hion, double *posp)
|
double re, double hion, double *posp)
|
||||||
{
|
{
|
||||||
double cosaz, rp, ap, sinap, tanap;
|
double cosaz, rp, ap, sinap, tanap;
|
||||||
|
const double D2R = (PI/180.0); /* deg to rad */
|
||||||
|
//const double R2D = (180.0/PI); /* rad to deg */
|
||||||
|
|
||||||
rp = re/(re+hion)*cos(azel[1]);
|
rp = re/(re+hion)*cos(azel[1]);
|
||||||
ap = PI/2.0-azel[1]-asin(rp);
|
ap = PI/2.0-azel[1]-asin(rp);
|
||||||
@ -250,8 +261,8 @@ double Sbas_Ionosphere_Correction::ionppp(const double *pos, const double *azel,
|
|||||||
cosaz = cos(azel[0]);
|
cosaz = cos(azel[0]);
|
||||||
posp[0] = asin(sin(pos[0])*cos(ap) + cos(pos[0])*sinap*cosaz);
|
posp[0] = asin(sin(pos[0])*cos(ap) + cos(pos[0])*sinap*cosaz);
|
||||||
|
|
||||||
if ((pos[0] > 70.0*D2R && tanap*cosaz > tan(PI/2.0-pos[0]))||
|
if ((pos[0] > 70.0*D2R && tanap*cosaz > tan(PI/2.0 - pos[0])) ||
|
||||||
(pos[0] < -70.0*D2R && - tanap*cosaz > tan(PI/2.0+pos[0])))
|
(pos[0] < -70.0*D2R && - tanap*cosaz > tan(PI/2.0 + pos[0])))
|
||||||
{
|
{
|
||||||
posp[1] = pos[1] + PI - asin(sinap*sin(azel[0])/cos(posp[0]));
|
posp[1] = pos[1] + PI - asin(sinap*sin(azel[0])/cos(posp[0]));
|
||||||
}
|
}
|
||||||
@ -259,7 +270,7 @@ double Sbas_Ionosphere_Correction::ionppp(const double *pos, const double *azel,
|
|||||||
{
|
{
|
||||||
posp[1] = pos[1] + asin(sinap*sin(azel[0])/cos(posp[0]));
|
posp[1] = pos[1] + asin(sinap*sin(azel[0])/cos(posp[0]));
|
||||||
}
|
}
|
||||||
return 1.0/sqrt(1.0-rp*rp);
|
return 1.0 / sqrt(1.0 - rp*rp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -270,7 +281,7 @@ double Sbas_Ionosphere_Correction::varicorr(int give)
|
|||||||
0.0084, 0.0333, 0.0749, 0.1331, 0.2079, 0.2994, 0.4075, 0.5322, 0.6735, 0.8315,
|
0.0084, 0.0333, 0.0749, 0.1331, 0.2079, 0.2994, 0.4075, 0.5322, 0.6735, 0.8315,
|
||||||
1.1974, 1.8709, 3.326, 20.787, 187.0826
|
1.1974, 1.8709, 3.326, 20.787, 187.0826
|
||||||
};
|
};
|
||||||
return 0<=give&&give<15?var[give]:0.0;
|
return 0 <= give && give < 15 ? var[give]:0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -280,6 +291,9 @@ void Sbas_Ionosphere_Correction::searchigp(const double *pos, const Igp **igp, d
|
|||||||
int i;
|
int i;
|
||||||
int latp[2];
|
int latp[2];
|
||||||
int lonp[4];
|
int lonp[4];
|
||||||
|
//const double D2R = (PI/180.0); /* deg to rad */
|
||||||
|
const double R2D = (180.0/PI); /* rad to deg */
|
||||||
|
|
||||||
double lat = pos[0]*R2D;
|
double lat = pos[0]*R2D;
|
||||||
double lon = pos[1]*R2D;
|
double lon = pos[1]*R2D;
|
||||||
|
|
||||||
@ -381,6 +395,8 @@ int Sbas_Ionosphere_Correction::sbsioncorr(const double sample_stamp, const doub
|
|||||||
double t;
|
double t;
|
||||||
double w[4] = {0};
|
double w[4] = {0};
|
||||||
const Igp *igp[4] = {0}; /* {ws,wn,es,en} */
|
const Igp *igp[4] = {0}; /* {ws,wn,es,en} */
|
||||||
|
//const double D2R = (PI/180.0); /* deg to rad */
|
||||||
|
const double R2D = (180.0/PI); /* rad to deg */
|
||||||
|
|
||||||
trace(4, "sbsioncorr: pos=%.3f %.3f azel=%.3f %.3f", pos[0]*R2D, pos[1]*R2D, azel[0]*R2D, azel[1]*R2D);
|
trace(4, "sbsioncorr: pos=%.3f %.3f azel=%.3f %.3f", pos[0]*R2D, pos[1]*R2D, azel[0]*R2D, azel[1]*R2D);
|
||||||
|
|
||||||
|
@ -63,6 +63,9 @@ private:
|
|||||||
ar & d_delay;
|
ar & d_delay;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Igp_Band
|
struct Igp_Band
|
||||||
{
|
{
|
||||||
//int d_iodi;
|
//int d_iodi;
|
||||||
@ -82,118 +85,135 @@ private:
|
|||||||
class Sbas_Ionosphere_Correction
|
class Sbas_Ionosphere_Correction
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// /* type definitions ----------------------------------------------------------*/
|
// /* type definitions ----------------------------------------------------------*/
|
||||||
//#define MAXBAND 10 /* max SBAS band of IGP */
|
//#define MAXBAND 10 /* max SBAS band of IGP */
|
||||||
//#define MAXNIGP 201 /* max number of IGP in SBAS band */
|
//#define MAXNIGP 201 /* max number of IGP in SBAS band */
|
||||||
//
|
//
|
||||||
// typedef struct { /* time struct */
|
// typedef struct { /* time struct */
|
||||||
// time_t time; /* time (s) expressed by standard time_t */
|
// time_t time; /* time (s) expressed by standard time_t */
|
||||||
// double sec; /* fraction of second under 1 s */
|
// double sec; /* fraction of second under 1 s */
|
||||||
// } gtime_t;
|
// } gtime_t;
|
||||||
//
|
//
|
||||||
// typedef struct { /* SBAS ionospheric correction type */
|
// typedef struct { /* SBAS ionospheric correction type */
|
||||||
// gtime_t t0; /* correction time */
|
// gtime_t t0; /* correction time */
|
||||||
// short lat,lon; /* latitude/longitude (deg) */
|
// short lat,lon; /* latitude/longitude (deg) */
|
||||||
// short give; /* GIVI+1 */
|
// short give; /* GIVI+1 */
|
||||||
// float delay; /* vertical delay estimate (m) */
|
// float delay; /* vertical delay estimate (m) */
|
||||||
// } sbsigp_t;
|
// } sbsigp_t;
|
||||||
//
|
//
|
||||||
// typedef struct { /* SBAS ionospheric corrections type */
|
// typedef struct { /* SBAS ionospheric corrections type */
|
||||||
// int iodi; /* IODI (issue of date ionos corr) */
|
// int iodi; /* IODI (issue of date ionos corr) */
|
||||||
// int nigp; /* number of igps */
|
// int nigp; /* number of igps */
|
||||||
// sbsigp_t igp[MAXNIGP]; /* ionospheric correction */
|
// sbsigp_t igp[MAXNIGP]; /* ionospheric correction */
|
||||||
// } sbsion_t;
|
// } sbsion_t;
|
||||||
|
|
||||||
/* inner product ---------------------------------------------------------------
|
|
||||||
* inner product of vectors
|
|
||||||
* args : double *a,*b I vector a,b (n x 1)
|
|
||||||
* int n I size of vector a,b
|
|
||||||
* return : a'*b
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
double dot(const double *a, const double *b, int n);
|
|
||||||
/* multiply matrix -----------------------------------------------------------*/
|
|
||||||
void matmul(const char *tr, int n, int k, int m, double alpha,
|
|
||||||
const double *A, const double *B, double beta, double *C);
|
|
||||||
/* ecef to local coordinate transfromation matrix ------------------------------
|
|
||||||
* compute ecef to local coordinate transfromation matrix
|
|
||||||
* args : double *pos I geodetic position {lat,lon} (rad)
|
|
||||||
* double *E O ecef to local coord transformation matrix (3x3)
|
|
||||||
* return : none
|
|
||||||
* notes : matirix stored by column-major order (fortran convention)
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
void xyz2enu(const double *pos, double *E);
|
|
||||||
/* transform ecef vector to local tangental coordinate -------------------------
|
|
||||||
* transform ecef vector to local tangental coordinate
|
|
||||||
* args : double *pos I geodetic position {lat,lon} (rad)
|
|
||||||
* double *r I vector in ecef coordinate {x,y,z}
|
|
||||||
* double *e O vector in local tangental coordinate {e,n,u}
|
|
||||||
* return : none
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
void ecef2enu(const double *pos, const double *r, double *e);
|
|
||||||
/* satellite azimuth/elevation angle -------------------------------------------
|
|
||||||
* compute satellite azimuth/elevation angle
|
|
||||||
* args : double *pos I geodetic position {lat,lon,h} (rad,m)
|
|
||||||
* double *e I receiver-to-satellilte unit vevtor (ecef)
|
|
||||||
* double *azel IO azimuth/elevation {az,el} (rad) (NULL: no output)
|
|
||||||
* (0.0<=azel[0]<2*pi,-pi/2<=azel[1]<=pi/2)
|
|
||||||
* return : elevation angle (rad)
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
double satazel(const double *pos, const double *e, double *azel);
|
|
||||||
|
|
||||||
/* debug trace functions -----------------------------------------------------*/
|
/*!
|
||||||
|
* \brief Inner product of vectors
|
||||||
|
* params : double *a,*b I vector a,b (n x 1)
|
||||||
|
* int n I size of vector a,b
|
||||||
|
* return : a'*b
|
||||||
|
*/
|
||||||
|
double dot(const double *a, const double *b, int n);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief multiply matrix
|
||||||
|
*/
|
||||||
|
void matmul(const char *tr, int n, int k, int m, double alpha,
|
||||||
|
const double *A, const double *B, double beta, double *C);
|
||||||
|
/*!
|
||||||
|
* \brief EFEC to local coordinate transfomartion matrix
|
||||||
|
* Compute ecef to local coordinate transfomartion matrix
|
||||||
|
* params : double *pos I geodetic position {lat,lon} (rad)
|
||||||
|
* double *E O ecef to local coord transformation matrix (3x3)
|
||||||
|
* return : none
|
||||||
|
* notes : matrix stored by column-major order (fortran convention)
|
||||||
|
*/
|
||||||
|
void xyz2enu(const double *pos, double *E);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Transforms ECEF vector into local tangential coordinates
|
||||||
|
* params : double *pos I geodetic position {lat,lon} (rad)
|
||||||
|
* double *r I vector in ecef coordinate {x,y,z}
|
||||||
|
* double *e O vector in local tangental coordinate {e,n,u}
|
||||||
|
* return : none
|
||||||
|
*/
|
||||||
|
void ecef2enu(const double *pos, const double *r, double *e);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Compute satellite azimuth/elevation angle
|
||||||
|
* params : double *pos I geodetic position {lat,lon,h} (rad,m)
|
||||||
|
* double *e I receiver-to-satellilte unit vevtor (ecef)
|
||||||
|
* double *azel IO azimuth/elevation {az,el} (rad) (NULL: no output)
|
||||||
|
* (0.0 <= azel[0] < 2*pi, -pi/2 <= azel[1] <= pi/2)
|
||||||
|
* return : elevation angle (rad)
|
||||||
|
*/
|
||||||
|
double satazel(const double *pos, const double *e, double *azel);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief debug trace functions
|
||||||
|
*/
|
||||||
void trace(int level, const char *format, ...);
|
void trace(int level, const char *format, ...);
|
||||||
|
|
||||||
/* time difference -------------------------------------------------------------
|
/* time difference -------------------------------------------------------------
|
||||||
* difference between gtime_t structs
|
* difference between gtime_t structs
|
||||||
* args : gtime_t t1,t2 I gtime_t structs
|
* args : gtime_t t1,t2 I gtime_t structs
|
||||||
* return : time difference (t1-t2) (s)
|
* return : time difference (t1-t2) (s)
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
//double timediff(gtime_t t1, gtime_t t2);
|
//double timediff(gtime_t t1, gtime_t t2);
|
||||||
/* ionospheric pierce point position -------------------------------------------
|
|
||||||
* compute ionospheric pierce point (ipp) position and slant factor
|
/*!
|
||||||
* args : double *pos I receiver position {lat,lon,h} (rad,m)
|
* \brief Compute ionospheric pierce point (ipp) position and slant factor
|
||||||
* double *azel I azimuth/elevation angle {az,el} (rad)
|
* params : double *pos I receiver position {lat,lon,h} (rad,m)
|
||||||
* double re I earth radius (km)
|
* double *azel I azimuth/elevation angle {az,el} (rad)
|
||||||
* double hion I altitude of ionosphere (km)
|
* double re I earth radius (km)
|
||||||
* double *posp O pierce point position {lat,lon,h} (rad,m)
|
* double hion I altitude of ionosphere (km)
|
||||||
* return : slant factor
|
* double *posp O pierce point position {lat,lon,h} (rad,m)
|
||||||
* notes : see ref [2], only valid on the earth surface
|
* return : slant factor
|
||||||
* fixing bug on ref [2] A.4.4.10.1 A-22,23
|
* notes : see ref [2], only valid on the earth surface
|
||||||
*-----------------------------------------------------------------------------*/
|
* fixing bug on ref [2] A.4.4.10.1 A-22,23
|
||||||
|
*-----------------------------------------------------------------------------*/
|
||||||
double ionppp(const double *pos, const double *azel, double re,
|
double ionppp(const double *pos, const double *azel, double re,
|
||||||
double hion, double *posp);
|
double hion, double *posp);
|
||||||
/* variance of ionosphere correction (give=GIVEI+1) --------------------------*/
|
|
||||||
|
/*!
|
||||||
|
* \brief Variance of ionosphere correction (give=GIVEI+1)
|
||||||
|
*/
|
||||||
double varicorr(int give);
|
double varicorr(int give);
|
||||||
/* search igps ---------------------------------------------------------------*/
|
|
||||||
|
/*!
|
||||||
|
* \brief Search igps
|
||||||
|
*/
|
||||||
void searchigp(const double *pos, const Igp **igp, double *x, double *y);
|
void searchigp(const double *pos, const Igp **igp, double *x, double *y);
|
||||||
/* sbas ionospheric delay correction -------------------------------------------
|
|
||||||
* compute sbas ionosphric delay correction
|
/*!
|
||||||
* args : long sample_stamp I sample stamp of observable on which the correction will be applied
|
* \brief Compute sbas ionosphric delay correction
|
||||||
* sbsion_t *ion I ionospheric correction data (implicit)
|
* params : long sample_stamp I sample stamp of observable on which the correction will be applied
|
||||||
* double *pos I receiver position {lat,lon,height} (rad/m)
|
* sbsion_t *ion I ionospheric correction data (implicit)
|
||||||
* double *azel I satellite azimuth/elavation angle (rad)
|
* double *pos I receiver position {lat,lon,height} (rad/m)
|
||||||
* double *delay O slant ionospheric delay (L1) (m)
|
* double *azel I satellite azimuth/elavation angle (rad)
|
||||||
* double *var O variance of ionospheric delay (m^2)
|
* double *delay O slant ionospheric delay (L1) (m)
|
||||||
* return : status (1:ok, 0:no correction)
|
* double *var O variance of ionospheric delay (m^2)
|
||||||
* notes : before calling the function, sbas ionosphere correction parameters
|
* return : status (1:ok, 0:no correction)
|
||||||
* in navigation data (nav->sbsion) must be set by callig
|
* notes : before calling the function, sbas ionosphere correction parameters
|
||||||
* sbsupdatecorr()
|
* in navigation data (nav->sbsion) must be set by callig
|
||||||
*-----------------------------------------------------------------------------*/
|
* sbsupdatecorr()
|
||||||
|
*/
|
||||||
int sbsioncorr(const double sample_stamp, const double *pos,
|
int sbsioncorr(const double sample_stamp, const double *pos,
|
||||||
const double *azel, double *delay, double *var);
|
const double *azel, double *delay, double *var);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::vector<Igp_Band> d_bands;
|
|
||||||
|
|
||||||
void print(std::ostream &out);
|
|
||||||
bool apply(double sample_stamp, double latitude_d, double longitude_d,
|
|
||||||
double azimut_d, double evaluation_d, double &delay, double &var);
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class boost::serialization::access;
|
friend class boost::serialization::access;
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
void serialize(Archive& ar, const unsigned int version){ar & d_bands;}
|
void serialize(Archive& ar, const unsigned int version){ar & d_bands;}
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::vector<Igp_Band> d_bands;
|
||||||
|
void print(std::ostream &out);
|
||||||
|
bool apply(double sample_stamp, double latitude_d, double longitude_d,
|
||||||
|
double azimut_d, double evaluation_d, double &delay, double &var);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,22 +34,25 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <glog/log_severity.h>
|
#include <glog/log_severity.h>
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
|
||||||
#include "sbas_satellite_correction.h"
|
#include "sbas_satellite_correction.h"
|
||||||
|
|
||||||
#define EVENT 2 // logs important events which don't occur every update() call
|
#define EVENT 2 // logs important events which don't occur every update() call
|
||||||
#define FLOW 3 // logs the function calls of block processing functions
|
#define FLOW 3 // logs the function calls of block processing functions
|
||||||
|
|
||||||
void
|
#define CLIGHT 299792458.0 /* speed of light (m/s) */
|
||||||
Sbas_Satellite_Correction::print(std::ostream &out)
|
#define MAXSBSAGEF 30.0 /* max age of SBAS fast correction (s) */
|
||||||
|
#define MAXSBSAGEL 1800.0 /* max age of SBAS long term corr (s) */
|
||||||
|
|
||||||
|
|
||||||
|
void Sbas_Satellite_Correction::print(std::ostream &out)
|
||||||
{
|
{
|
||||||
out << "<<S>> Sbas satellite corrections for PRN" << d_prn << ":" << std::endl;
|
out << "<<S>> Sbas satellite corrections for PRN" << d_prn << ":" << std::endl;
|
||||||
print_fast_correction(out);
|
print_fast_correction(out);
|
||||||
print_long_term_correction(out);
|
print_long_term_correction(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Sbas_Satellite_Correction::print_fast_correction(std::ostream &out)
|
void Sbas_Satellite_Correction::print_fast_correction(std::ostream &out)
|
||||||
{
|
{
|
||||||
Fast_Correction fcorr = d_fast_correction;
|
Fast_Correction fcorr = d_fast_correction;
|
||||||
out << "<<S>> Fast PRN" << d_prn << ":";
|
out << "<<S>> Fast PRN" << d_prn << ":";
|
||||||
@ -73,8 +76,7 @@ Sbas_Satellite_Correction::print_fast_correction(std::ostream &out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void Sbas_Satellite_Correction::print_long_term_correction(std::ostream &out)
|
||||||
Sbas_Satellite_Correction::print_long_term_correction(std::ostream &out)
|
|
||||||
{
|
{
|
||||||
Long_Term_Correction lcorr = d_long_term_correction;
|
Long_Term_Correction lcorr = d_long_term_correction;
|
||||||
out << "<<S>> Long PRN" << d_prn << ":";
|
out << "<<S>> Long PRN" << d_prn << ":";
|
||||||
@ -94,178 +96,163 @@ int Sbas_Satellite_Correction::apply_fast(double sample_stamp, double &pr, doubl
|
|||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
double prc = 0; // pseudo range correction
|
double prc = 0; // pseudo range correction
|
||||||
|
|
||||||
result = sbsfastcorr(sample_stamp, &prc, &var);
|
result = sbsfastcorr(sample_stamp, &prc, &var);
|
||||||
|
|
||||||
pr += prc;
|
pr += prc;
|
||||||
|
|
||||||
VLOG(FLOW) << "<<S>> fast correction applied: sample_stamp=" << sample_stamp << " prc=" << prc << " corr. pr=" << pr;
|
VLOG(FLOW) << "<<S>> fast correction applied: sample_stamp=" << sample_stamp << " prc=" << prc << " corr. pr=" << pr;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int Sbas_Satellite_Correction::apply_long_term_sv_pos(double sample_stamp, double sv_pos[], double &var)
|
int Sbas_Satellite_Correction::apply_long_term_sv_pos(double sample_stamp, double sv_pos[], double &var)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
double drs[3] = {0};
|
double drs[3] = {0};
|
||||||
double ddts = 0;
|
double ddts = 0;
|
||||||
|
|
||||||
result = sbslongcorr(sample_stamp, drs, &ddts);
|
result = sbslongcorr(sample_stamp, drs, &ddts);
|
||||||
for (int i = 0; i < 3; i++) sv_pos[i] += drs[i];
|
for (int i = 0; i < 3; i++) sv_pos[i] += drs[i];
|
||||||
|
|
||||||
VLOG(FLOW) << "<<S>> long term sv pos correction applied: sample_stamp=" << sample_stamp << " drs=(x=" << drs[0] << " y=" << drs[1] << " z=" << drs[2] << ")";
|
VLOG(FLOW) << "<<S>> long term sv pos correction applied: sample_stamp=" << sample_stamp << " drs=(x=" << drs[0] << " y=" << drs[1] << " z=" << drs[2] << ")";
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int Sbas_Satellite_Correction::apply_long_term_sv_clk(double sample_stamp, double &dts, double &var)
|
int Sbas_Satellite_Correction::apply_long_term_sv_clk(double sample_stamp, double &dts, double &var)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
double drs[3] = {0};
|
double drs[3] = {0};
|
||||||
double ddts = 0;
|
double ddts = 0;
|
||||||
|
|
||||||
result = sbslongcorr(sample_stamp, drs, &ddts);
|
result = sbslongcorr(sample_stamp, drs, &ddts);
|
||||||
dts += ddts;
|
dts += ddts;
|
||||||
|
|
||||||
VLOG(FLOW) << "<<S>> long term sv clock correction correction applied: sample_stamp=" << sample_stamp << " ddts=" << ddts;
|
VLOG(FLOW) << "<<S>> long term sv clock correction correction applied: sample_stamp=" << sample_stamp << " ddts=" << ddts;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Sbas_Satellite_Correction::alarm()
|
bool Sbas_Satellite_Correction::alarm()
|
||||||
{
|
{
|
||||||
return this->d_fast_correction.d_udre == 16;
|
return this->d_fast_correction.d_udre == 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define CLIGHT 299792458.0 /* speed of light (m/s) */
|
|
||||||
#define MAXSBSAGEF 30.0 /* max age of SBAS fast correction (s) */
|
|
||||||
#define MAXSBSAGEL 1800.0 /* max age of SBAS long term corr (s) */
|
|
||||||
|
|
||||||
/* debug trace function -----------------------------------------------------*/
|
/* debug trace function -----------------------------------------------------*/
|
||||||
void Sbas_Satellite_Correction::trace(int level, const char *format, ...)
|
void Sbas_Satellite_Correction::trace(int level, const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char str[1000];
|
char str[1000];
|
||||||
|
|
||||||
va_start(ap,format);
|
va_start(ap,format);
|
||||||
vsprintf(str,format,ap);
|
vsprintf(str,format,ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
VLOG(FLOW) << "<<S>> " << std::string(str);
|
VLOG(FLOW) << "<<S>> " << std::string(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* variance of fast correction (udre=UDRE+1) ---------------------------------*/
|
/* variance of fast correction (udre=UDRE+1) ---------------------------------*/
|
||||||
double Sbas_Satellite_Correction::varfcorr(int udre)
|
double Sbas_Satellite_Correction::varfcorr(int udre)
|
||||||
{
|
{
|
||||||
const double var[14] = {
|
const double var[14] = {
|
||||||
0.052,0.0924,0.1444,0.283,0.4678,0.8315,1.2992,1.8709,2.5465,3.326,
|
0.052, 0.0924, 0.1444, 0.283, 0.4678, 0.8315, 1.2992, 1.8709, 2.5465, 3.326,
|
||||||
5.1968,20.7870,230.9661,2078.695
|
5.1968, 20.7870, 230.9661, 2078.695
|
||||||
};
|
};
|
||||||
return 0 < udre && udre <= 14 ? var[udre-1]:0.0;
|
return 0 < udre && udre <= 14 ? var[udre - 1] : 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* fast correction degradation -----------------------------------------------*/
|
/* fast correction degradation -----------------------------------------------*/
|
||||||
double Sbas_Satellite_Correction::degfcorr(int ai)
|
double Sbas_Satellite_Correction::degfcorr(int ai)
|
||||||
{
|
{
|
||||||
const double degf[16] = {
|
const double degf[16] = {
|
||||||
0.00000,0.00005,0.00009,0.00012,0.00015,0.00020,0.00030,0.00045,
|
0.00000, 0.00005, 0.00009, 0.00012, 0.00015, 0.00020, 0.00030, 0.00045,
|
||||||
0.00060,0.00090,0.00150,0.00210,0.00270,0.00330,0.00460,0.00580
|
0.00060, 0.00090, 0.00150, 0.00210, 0.00270, 0.00330, 0.00460, 0.00580
|
||||||
};
|
};
|
||||||
return 0 < ai && ai <= 15 ? degf[ai]:0.0058;
|
return 0 < ai && ai <= 15 ? degf[ai] : 0.0058;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* long term correction ------------------------------------------------------*/
|
/* long term correction ------------------------------------------------------*/
|
||||||
int Sbas_Satellite_Correction::sbslongcorr(double time_stamp, double *drs, double *ddts)
|
int Sbas_Satellite_Correction::sbslongcorr(double time_stamp, double *drs, double *ddts)
|
||||||
{
|
{
|
||||||
double t = 0.0;
|
double t = 0.0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
Long_Term_Correction lcorr = d_long_term_correction;
|
Long_Term_Correction lcorr = d_long_term_correction;
|
||||||
|
|
||||||
trace(3, "sbslongcorr: prn=%2d", this->d_prn);
|
trace(3, "sbslongcorr: prn=%2d", this->d_prn);
|
||||||
|
// if (p->sat!=sat||p->lcorr.t0.time==0) continue;
|
||||||
// if (p->sat!=sat||p->lcorr.t0.time==0) continue;
|
|
||||||
|
|
||||||
// compute time of applicability
|
// compute time of applicability
|
||||||
if(d_long_term_correction.i_vel == 1)
|
if(d_long_term_correction.i_vel == 1)
|
||||||
{ // time of applicability is the one sent, i.e., tapp
|
{
|
||||||
// TODO: adapt for vel==1 case
|
// time of applicability is the one sent, i.e., tapp
|
||||||
// t = tow-d_long_term_correction.i_tapp;
|
// TODO: adapt for vel==1 case
|
||||||
// vel=1 -> time of applicability is sent in message, needs to be corrected for rollover which can not be done here, since the absolute gps time is unknown. see IS-GPS-200G pdf page 116 for correction
|
// t = tow-d_long_term_correction.i_tapp;
|
||||||
/* t = (int)getbitu(msg->msg, p + 90, 13)*16 - (int)msg->tow%86400;
|
// vel=1 -> time of applicability is sent in message, needs to be corrected for rollover which can not be done here, since the absolute gps time is unknown. see IS-GPS-200G pdf page 116 for correction
|
||||||
if (t <= -43200) t += 86400;
|
/* t = (int)getbitu(msg->msg, p + 90, 13)*16 - (int)msg->tow%86400;
|
||||||
else if (t > 43200) t -= 86400;
|
if (t <= -43200) t += 86400;
|
||||||
sbssat->sat[n-1].lcorr.t0 = gpst2time(msg->week, msg->tow + t);*/
|
else if (t > 43200) t -= 86400;
|
||||||
}
|
sbssat->sat[n-1].lcorr.t0 = gpst2time(msg->week, msg->tow + t);*/
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{ // time of applicability is time of reception
|
{
|
||||||
t = time_stamp - lcorr.d_trx; // should not have any impact if vel==0 since d_dvel and d_daf1 are zero, is only used to check outdating
|
// time of applicability is time of reception
|
||||||
}
|
t = time_stamp - lcorr.d_trx; // should not have any impact if vel==0 since d_dvel and d_daf1 are zero, is only used to check outdating
|
||||||
|
}
|
||||||
//t=time_stamp-lcorr.d_t0;
|
//t=time_stamp-lcorr.d_t0;
|
||||||
|
if (fabs(t) > MAXSBSAGEL)
|
||||||
if (fabs(t) > MAXSBSAGEL)
|
{
|
||||||
{
|
trace(2,"sbas long-term correction expired: sat=%2d time_stamp=%5.0f", d_prn, time_stamp);
|
||||||
trace(2,"sbas long-term correction expired: sat=%2d time_stamp=%5.0f", d_prn, time_stamp);
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
// sv position correction
|
||||||
|
for (i=0; i<3; i++) drs[i] = lcorr.d_dpos[i] + lcorr.d_dvel[i]*t;
|
||||||
// sv position correction
|
// sv clock correction correction
|
||||||
for (i=0; i<3; i++) drs[i] = lcorr.d_dpos[i] + lcorr.d_dvel[i]*t;
|
*ddts = lcorr.d_daf0 + lcorr.d_daf1*t;
|
||||||
|
trace(5, "sbslongcorr: sat=%2d drs=%7.2f%7.2f%7.2f ddts=%7.2f", d_prn, drs[0], drs[1], drs[2], *ddts * CLIGHT);
|
||||||
// sv clock correction correction
|
return 1;
|
||||||
*ddts = lcorr.d_daf0 + lcorr.d_daf1*t;
|
|
||||||
|
|
||||||
trace(5, "sbslongcorr: sat=%2d drs=%7.2f%7.2f%7.2f ddts=%7.2f", d_prn, drs[0], drs[1], drs[2], *ddts*CLIGHT);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* if sbas satellite without correction, no correction applied */
|
/* if sbas satellite without correction, no correction applied */
|
||||||
//if (satsys(sat,NULL)==SYS_SBS) return 1;
|
//if (satsys(sat,NULL)==SYS_SBS) return 1;
|
||||||
|
|
||||||
//trace(2,"no sbas long-term correction: %s sat=%2d\n",time_str(time,0),sat);
|
//trace(2,"no sbas long-term correction: %s sat=%2d\n",time_str(time,0),sat);
|
||||||
//return 0;
|
//return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* fast correction -----------------------------------------------------------*/
|
/* fast correction -----------------------------------------------------------*/
|
||||||
int Sbas_Satellite_Correction::sbsfastcorr(double time_stamp, double *prc, double *var)
|
int Sbas_Satellite_Correction::sbsfastcorr(double time_stamp, double *prc, double *var)
|
||||||
#define RRCENA
|
#define RRCENA
|
||||||
{
|
{
|
||||||
double t;
|
double t;
|
||||||
|
|
||||||
Fast_Correction fcorr = d_fast_correction;
|
Fast_Correction fcorr = d_fast_correction;
|
||||||
|
|
||||||
trace(3, "sbsfastcorr: sat=%2d", this->d_prn);
|
trace(3, "sbsfastcorr: sat=%2d", this->d_prn);
|
||||||
|
//if (p->fcorr.t0.time==0) break; // time==0is only true if t0 hasn't been initialised -> it checks if the correction is valid
|
||||||
//if (p->fcorr.t0.time==0) break; // time==0is only true if t0 hasn't been initialised -> it checks if the correction is valid
|
t = (time_stamp - fcorr.d_tof.get_time_stamp()) + fcorr.d_tlat; // delta t between now and tof
|
||||||
t = (time_stamp - fcorr.d_tof.get_time_stamp()) + fcorr.d_tlat; // delta t between now and tof
|
/* expire age of correction? */
|
||||||
|
if (fabs(t) > MAXSBSAGEF)
|
||||||
/* expire age of correction? */
|
{
|
||||||
if (fabs(t) > MAXSBSAGEF)
|
trace(2, "no sbas fast correction (expired): time_stamp=%f prn=%2d", time_stamp, d_prn);
|
||||||
{
|
return 0;
|
||||||
trace(2, "no sbas fast correction (expired): time_stamp=%f prn=%2d", time_stamp, d_prn);
|
}
|
||||||
return 0;
|
/* UDRE==14 (not monitored)? */
|
||||||
}
|
else if(fcorr.d_udre == 15)
|
||||||
/* UDRE==14 (not monitored)? */
|
{
|
||||||
else if(fcorr.d_udre == 15)
|
trace(2,"no sbas fast correction (not monitored): time_stamp=%f prn=%2d", time_stamp, d_prn);
|
||||||
{
|
return 0;
|
||||||
trace(2,"no sbas fast correction (not monitored): time_stamp=%f prn=%2d", time_stamp, d_prn);
|
}
|
||||||
return 0;
|
else if(fcorr.d_udre == 16)
|
||||||
}
|
{
|
||||||
else if(fcorr.d_udre == 16)
|
trace(2,"SV is marked as unhealthy: time_stamp=%f prn=%2d", time_stamp, d_prn);
|
||||||
{
|
return 0;
|
||||||
trace(2,"SV is marked as unhealthy: time_stamp=%f prn=%2d", time_stamp, d_prn);
|
}
|
||||||
return 0;
|
*prc = fcorr.d_prc;
|
||||||
}
|
|
||||||
*prc = fcorr.d_prc;
|
|
||||||
#ifdef RRCENA
|
#ifdef RRCENA
|
||||||
if (fcorr.d_ai > 0 && fabs(t) <= 8.0*fcorr.d_dt)
|
if (fcorr.d_ai > 0 && fabs(t) <= 8.0*fcorr.d_dt)
|
||||||
{
|
{
|
||||||
*prc += fcorr.d_rrc*t;
|
*prc += fcorr.d_rrc*t;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
*var = varfcorr(fcorr.d_udre) + degfcorr(fcorr.d_ai)*t*t/2.0;
|
*var = varfcorr(fcorr.d_udre) + degfcorr(fcorr.d_ai) * t * t / 2.0;
|
||||||
|
trace(5, "sbsfastcorr: sat=%3d prc=%7.2f sig=%7.2f t=%5.0f", d_prn, *prc, sqrt(*var), t);
|
||||||
trace(5, "sbsfastcorr: sat=%3d prc=%7.2f sig=%7.2f t=%5.0f", d_prn, *prc, sqrt(*var), t);
|
return 1;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -289,9 +276,7 @@ int Sbas_Satellite_Correction::sbssatcorr(double time_stamp, double *rs, double
|
|||||||
{
|
{
|
||||||
double drs[3] = {0}, dclk = 0.0, prc = 0.0;
|
double drs[3] = {0}, dclk = 0.0, prc = 0.0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
trace(3,"sbssatcorr : sat=%2d",d_prn);
|
trace(3,"sbssatcorr : sat=%2d",d_prn);
|
||||||
|
|
||||||
/* sbas long term corrections */
|
/* sbas long term corrections */
|
||||||
if (!sbslongcorr(time_stamp, drs, &dclk))
|
if (!sbslongcorr(time_stamp, drs, &dclk))
|
||||||
{
|
{
|
||||||
@ -303,12 +288,9 @@ int Sbas_Satellite_Correction::sbssatcorr(double time_stamp, double *rs, double
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (i=0; i<3; i++) rs[i] += drs[i];
|
for (i=0; i<3; i++) rs[i] += drs[i];
|
||||||
|
|
||||||
dts[0] += dclk + prc/CLIGHT;
|
dts[0] += dclk + prc/CLIGHT;
|
||||||
|
|
||||||
trace(5,"sbssatcorr: sat=%2d drs=%6.3f %6.3f %6.3f dclk=%.3f %.3f var=%.3f",
|
trace(5,"sbssatcorr: sat=%2d drs=%6.3f %6.3f %6.3f dclk=%.3f %.3f var=%.3f",
|
||||||
d_prn,drs[0],drs[1],drs[2],dclk,prc/CLIGHT,*var);
|
d_prn,drs[0],drs[1],drs[2],dclk,prc/CLIGHT,*var);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
Sbas_Telemetry_Data::Sbas_Telemetry_Data()
|
Sbas_Telemetry_Data::Sbas_Telemetry_Data()
|
||||||
{
|
{
|
||||||
fp_trace = NULL; /* file pointer of trace */
|
fp_trace = nullptr;; /* file pointer of trace */
|
||||||
level_trace = 0; /* level of trace */
|
level_trace = 0; /* level of trace */
|
||||||
tick_trace = 0; /* tick time at traceopen (ms) */
|
tick_trace = 0; /* tick time at traceopen (ms) */
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ void Sbas_Telemetry_Data::updated_sbas_ephemeris(Sbas_Raw_Msg msg)
|
|||||||
|
|
||||||
Sbas_Ephemeris seph;
|
Sbas_Ephemeris seph;
|
||||||
|
|
||||||
int satidx = msg.get_prn()-MINPRNSBS;
|
int satidx = msg.get_prn() - MINPRNSBS;
|
||||||
seph_t seph_rtklib = d_nav.seph[satidx];
|
seph_t seph_rtklib = d_nav.seph[satidx];
|
||||||
|
|
||||||
// copy data
|
// copy data
|
||||||
@ -237,8 +237,9 @@ void Sbas_Telemetry_Data::received_iono_correction()
|
|||||||
if(iono_queue != NULL) iono_queue->push(iono_corr);
|
if(iono_queue != NULL) iono_queue->push(iono_corr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// helper for comparing two POD structures with undefined padding between members
|
// helper for comparing two POD structures with undefined padding between members
|
||||||
// not garanted to work always properly -> don't use it for critical tasks
|
// not guaranteed to work always properly -> don't use it for critical tasks
|
||||||
template <class Struct>
|
template <class Struct>
|
||||||
inline bool are_equal(const Struct &s1, const Struct &s2)
|
inline bool are_equal(const Struct &s1, const Struct &s2)
|
||||||
{
|
{
|
||||||
@ -254,31 +255,11 @@ inline bool are_equal(const Struct &s1, const Struct &s2)
|
|||||||
s1_ = (Struct*) calloc (1, struct_size);
|
s1_ = (Struct*) calloc (1, struct_size);
|
||||||
s2_ = (Struct*) calloc (1, struct_size);
|
s2_ = (Struct*) calloc (1, struct_size);
|
||||||
|
|
||||||
/* is_equal = !memcmp(s1_, s2_, sizeof(Struct));
|
// use assignment constructor which doesn't copy paddings
|
||||||
|
|
||||||
bool is_equal_manual = true;
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "\n<<cmp>> compare original objects of size=" << sizeof(Struct) << ":" << std::endl;
|
|
||||||
for (size_t i = 0; i < sizeof(Struct); ++i)
|
|
||||||
{
|
|
||||||
char byte1 = ((const char *)&s1)[i];
|
|
||||||
char byte2 = ((const char *)&s2)[i];
|
|
||||||
if(byte1 != byte2) is_equal_manual = false;
|
|
||||||
ss << "<<cmp>> s1=" << std::hex << std::setw(4) << std::setfill('0');
|
|
||||||
ss << (short)byte1;
|
|
||||||
ss << " s2=" << std::hex << std::setw(4) << std::setfill('0');
|
|
||||||
ss << (short)byte2;
|
|
||||||
ss << " equal=" << is_equal_manual;
|
|
||||||
ss << std::endl;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// use asignment constructor which doesn't copy paddings
|
|
||||||
*s1_ = s1;
|
*s1_ = s1;
|
||||||
*s2_ = s2;
|
*s2_ = s2;
|
||||||
|
|
||||||
// compare struct memory byte-wise
|
// compare struct memory byte-wise
|
||||||
//is_equal = !memcmp(s1_, s2_, sizeof(Struct));
|
|
||||||
|
|
||||||
is_equal_manual = true;
|
is_equal_manual = true;
|
||||||
ss.str();
|
ss.str();
|
||||||
ss << "\n<<cmp>> compare objects of size=" << sizeof(Struct) << " (memcmp says is_equal=" << is_equal << ") :" << std::endl;
|
ss << "\n<<cmp>> compare objects of size=" << sizeof(Struct) << " (memcmp says is_equal=" << is_equal << ") :" << std::endl;
|
||||||
@ -294,7 +275,6 @@ inline bool are_equal(const Struct &s1, const Struct &s2)
|
|||||||
ss << " equal=" << is_equal_manual;
|
ss << " equal=" << is_equal_manual;
|
||||||
ss << std::endl;
|
ss << std::endl;
|
||||||
}
|
}
|
||||||
//VLOG(DETAIL) << ss.str();
|
|
||||||
|
|
||||||
free(s1_);
|
free(s1_);
|
||||||
free(s2_);
|
free(s2_);
|
||||||
@ -307,7 +287,7 @@ inline bool are_equal(const Struct &s1, const Struct &s2)
|
|||||||
void Sbas_Telemetry_Data::updated_satellite_corrections()
|
void Sbas_Telemetry_Data::updated_satellite_corrections()
|
||||||
{
|
{
|
||||||
VLOG(FLOW) << "<<T>> updated_satellite_corrections():";
|
VLOG(FLOW) << "<<T>> updated_satellite_corrections():";
|
||||||
// for each satellit in the RTKLIB structure
|
// for each satellite in the RTKLIB structure
|
||||||
for (int i_sat = 0; i_sat < d_nav.sbssat.nsat; i_sat++)
|
for (int i_sat = 0; i_sat < d_nav.sbssat.nsat; i_sat++)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@ -404,7 +384,6 @@ void Sbas_Telemetry_Data::trace(int level, const char *format, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char str[1000];
|
char str[1000];
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
vsprintf(str, format, ap);
|
vsprintf(str, format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
@ -433,7 +412,7 @@ int Sbas_Telemetry_Data::satno(int sys, int prn)
|
|||||||
return NSATGPS + NSATGLO + prn - MINPRNGAL + 1;
|
return NSATGPS + NSATGLO + prn - MINPRNGAL + 1;
|
||||||
case SYS_QZS:
|
case SYS_QZS:
|
||||||
if (prn < MINPRNQZS || MAXPRNQZS < prn) return 0;
|
if (prn < MINPRNQZS || MAXPRNQZS < prn) return 0;
|
||||||
return NSATGPS+NSATGLO+NSATGAL+prn-MINPRNQZS+1;
|
return NSATGPS + NSATGLO + NSATGAL + prn - MINPRNQZS + 1;
|
||||||
case SYS_CMP:
|
case SYS_CMP:
|
||||||
if (prn < MINPRNCMP || MAXPRNCMP < prn) return 0;
|
if (prn < MINPRNCMP || MAXPRNCMP < prn) return 0;
|
||||||
return NSATGPS + NSATGLO + NSATGAL + NSATQZS + prn - MINPRNCMP + 1;
|
return NSATGPS + NSATGLO + NSATGAL + NSATQZS + prn - MINPRNCMP + 1;
|
||||||
@ -443,13 +422,14 @@ int Sbas_Telemetry_Data::satno(int sys, int prn)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* extract unsigned/signed bits ------------------------------------------------
|
|
||||||
* extract unsigned/signed bits from byte data
|
/*!
|
||||||
* args : unsigned char *buff I byte data
|
* \brief Extracts unsigned/signed bits from byte data
|
||||||
|
* params : unsigned char *buff I byte data
|
||||||
* int pos I bit position from start of data (bits)
|
* int pos I bit position from start of data (bits)
|
||||||
* int len I bit length (bits) (len<=32)
|
* int len I bit length (bits) (len<=32)
|
||||||
* return : extracted unsigned/signed bits
|
* return : extracted unsigned/signed bits
|
||||||
*-----------------------------------------------------------------------------*/
|
*/
|
||||||
unsigned int Sbas_Telemetry_Data::getbitu(const unsigned char *buff, int pos, int len)
|
unsigned int Sbas_Telemetry_Data::getbitu(const unsigned char *buff, int pos, int len)
|
||||||
{
|
{
|
||||||
unsigned int bits = 0;
|
unsigned int bits = 0;
|
||||||
@ -479,12 +459,12 @@ Sbas_Telemetry_Data::gtime_t Sbas_Telemetry_Data::epoch2time(const double *ep)
|
|||||||
{
|
{
|
||||||
const int doy[]={1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
|
const int doy[]={1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
|
||||||
gtime_t time = {0};
|
gtime_t time = {0};
|
||||||
int days, sec, year = (int)ep[0], mon=(int)ep[1], day=(int)ep[2];
|
int days, sec, year = (int)ep[0], mon = (int)ep[1], day = (int)ep[2];
|
||||||
|
|
||||||
if (year<1970 || 2099<year || mon<1 || 12<mon) return time;
|
if (year < 1970 || 2099 < year || mon < 1 || 12 < mon) return time;
|
||||||
|
|
||||||
/* leap year if year%4==0 in 1901-2099 */
|
/* leap year if year%4==0 in 1901-2099 */
|
||||||
days = (year - 1970)*365 + (year - 1969)/4 + doy[mon-1] + day -2 + (year%4==0&&mon>=3?1:0);
|
days = (year - 1970)*365 + (year - 1969)/4 + doy[mon - 1] + day - 2 + (year % 4 == 0 && mon >= 3 ? 1 : 0);
|
||||||
sec = (int)floor(ep[5]);
|
sec = (int)floor(ep[5]);
|
||||||
time.time = (time_t)days*86400 + (int)ep[3]*3600 + (int)ep[4]*60 + sec;
|
time.time = (time_t)days*86400 + (int)ep[3]*3600 + (int)ep[4]*60 + sec;
|
||||||
time.sec = ep[5] - sec;
|
time.sec = ep[5] - sec;
|
||||||
@ -579,8 +559,8 @@ const Sbas_Telemetry_Data::sbsigpband_t Sbas_Telemetry_Data::igpband2[2][5]={ /*
|
|||||||
/* decode type 1: prn masks --------------------------------------------------*/
|
/* decode type 1: prn masks --------------------------------------------------*/
|
||||||
int Sbas_Telemetry_Data::decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat)
|
int Sbas_Telemetry_Data::decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat)
|
||||||
{
|
{
|
||||||
int i,n,sat;
|
int i, n, sat;
|
||||||
// see figure A-6: i coresponds to bit number (and for the GPS satellites is identically to the PRN), n to the PRN mask number
|
// see figure A-6: i corresponds to bit number (and for the GPS satellites is identically to the PRN), n to the PRN mask number
|
||||||
|
|
||||||
trace(4,"decode_sbstype1:");
|
trace(4,"decode_sbstype1:");
|
||||||
|
|
||||||
@ -588,14 +568,14 @@ int Sbas_Telemetry_Data::decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat)
|
|||||||
{
|
{
|
||||||
if (getbitu(msg->msg, 13+i, 1))
|
if (getbitu(msg->msg, 13+i, 1))
|
||||||
{
|
{
|
||||||
if (i <= 37) sat = satno(SYS_GPS, i); /* 0- 37: gps */
|
if (i <= 37) sat = satno(SYS_GPS, i); /* 0- 37: gps */
|
||||||
else if (i <= 61) sat = satno(SYS_GLO, i - 37); /* 38- 61: glonass */
|
else if (i <= 61) sat = satno(SYS_GLO, i - 37); /* 38- 61: glonass */
|
||||||
else if (i <= 119) sat = 0; /* 62-119: future gnss */
|
else if (i <= 119) sat = 0; /* 62-119: future gnss */
|
||||||
else if (i <= 138) sat = satno(SYS_SBS, i); /* 120-138: geo/waas */
|
else if (i <= 138) sat = satno(SYS_SBS, i); /* 120-138: geo/waas */
|
||||||
else if (i <= 182) sat = 0; /* 139-182: reserved */
|
else if (i <= 182) sat = 0; /* 139-182: reserved */
|
||||||
else if (i <= 192) sat = satno(SYS_SBS,i+10); /* 183-192: qzss ref [2] */
|
else if (i <= 192) sat = satno(SYS_SBS, i + 10); /* 183-192: qzss ref [2] */
|
||||||
else if (i <= 202) sat = satno(SYS_QZS, i); /* 193-202: qzss ref [2] */
|
else if (i <= 202) sat = satno(SYS_QZS, i); /* 193-202: qzss ref [2] */
|
||||||
else sat = 0; /* 203- : reserved */
|
else sat = 0; /* 203- : reserved */
|
||||||
sbssat->sat[n++].sat = sat;
|
sbssat->sat[n++].sat = sat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -608,6 +588,8 @@ int Sbas_Telemetry_Data::decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat)
|
|||||||
trace(5, "decode_sbstype1: nprn=%d iodp=%d", n, sbssat->iodp);
|
trace(5, "decode_sbstype1: nprn=%d iodp=%d", n, sbssat->iodp);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* decode type 2-5,0: fast corrections ---------------------------------------*/
|
/* decode type 2-5,0: fast corrections ---------------------------------------*/
|
||||||
int Sbas_Telemetry_Data::decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat)
|
int Sbas_Telemetry_Data::decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat)
|
||||||
{
|
{
|
||||||
@ -617,20 +599,20 @@ int Sbas_Telemetry_Data::decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat)
|
|||||||
|
|
||||||
trace(4,"decode_sbstype2:");
|
trace(4,"decode_sbstype2:");
|
||||||
|
|
||||||
if (sbssat->iodp!=(int)getbitu(msg->msg,16,2)) return 0;
|
if (sbssat->iodp != (int)getbitu(msg->msg, 16, 2)) return 0;
|
||||||
|
|
||||||
type = getbitu(msg->msg, 8, 6);
|
type = getbitu(msg->msg, 8, 6);
|
||||||
iodf = getbitu(msg->msg, 14, 2);
|
iodf = getbitu(msg->msg, 14, 2);
|
||||||
|
|
||||||
for (i=0; i<13; i++)
|
for (i=0; i<13; i++)
|
||||||
{
|
{
|
||||||
if ((j = 13*((type==0?2:type)-2)+i) >= sbssat->nsat) break;
|
if ((j = 13*((type == 0 ? 2 : type) - 2) + i) >= sbssat->nsat) break;
|
||||||
udrei = getbitu(msg->msg, 174 + 4*i, 4);
|
udrei = getbitu(msg->msg, 174 + 4*i, 4);
|
||||||
t0_past = sbssat->sat[j].fcorr.t0;
|
t0_past = sbssat->sat[j].fcorr.t0;
|
||||||
prc = sbssat->sat[j].fcorr.prc;
|
prc = sbssat->sat[j].fcorr.prc;
|
||||||
sbssat->sat[j].fcorr.t0 = msg->sample_stamp;
|
sbssat->sat[j].fcorr.t0 = msg->sample_stamp;
|
||||||
sbssat->sat[j].fcorr.prc = getbits(msg->msg, 18 + i*12, 12)*0.125f;
|
sbssat->sat[j].fcorr.prc = getbits(msg->msg, 18 + i*12, 12)*0.125f;
|
||||||
sbssat->sat[j].fcorr.udre = udrei+1;
|
sbssat->sat[j].fcorr.udre = udrei + 1;
|
||||||
dt = sbssat->sat[j].fcorr.t0 - t0_past;
|
dt = sbssat->sat[j].fcorr.t0 - t0_past;
|
||||||
if (!sbssat->sat[j].fcorr.valid || dt <= 0.0 || 18.0 < dt || sbssat->sat[j].fcorr.ai == 0)
|
if (!sbssat->sat[j].fcorr.valid || dt <= 0.0 || 18.0 < dt || sbssat->sat[j].fcorr.ai == 0)
|
||||||
{
|
{
|
||||||
@ -639,7 +621,7 @@ int Sbas_Telemetry_Data::decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sbssat->sat[j].fcorr.rrc = (sbssat->sat[j].fcorr.prc-prc)/dt;
|
sbssat->sat[j].fcorr.rrc = (sbssat->sat[j].fcorr.prc - prc)/dt;
|
||||||
sbssat->sat[j].fcorr.dt = dt;
|
sbssat->sat[j].fcorr.dt = dt;
|
||||||
}
|
}
|
||||||
sbssat->sat[j].fcorr.valid = true;
|
sbssat->sat[j].fcorr.valid = true;
|
||||||
@ -669,7 +651,7 @@ int Sbas_Telemetry_Data::decode_sbstype6(const sbsmsg_t *msg, sbssat_t *sbssat)
|
|||||||
{
|
{
|
||||||
if (!sbssat->sat[i].fcorr.valid || sbssat->sat[i].fcorr.iodf != iodf[i/13]) continue;
|
if (!sbssat->sat[i].fcorr.valid || sbssat->sat[i].fcorr.iodf != iodf[i/13]) continue;
|
||||||
udrei = getbitu(msg->msg, 22 + i*4, 4);
|
udrei = getbitu(msg->msg, 22 + i*4, 4);
|
||||||
sbssat->sat[i].fcorr.udre = udrei+1;
|
sbssat->sat[i].fcorr.udre = udrei + 1;
|
||||||
}
|
}
|
||||||
trace(5, "decode_sbstype6: iodf=%d %d %d %d", iodf[0], iodf[1], iodf[2], iodf[3]);
|
trace(5, "decode_sbstype6: iodf=%d %d %d %d", iodf[0], iodf[1], iodf[2], iodf[3]);
|
||||||
return 1;
|
return 1;
|
||||||
@ -681,13 +663,9 @@ int Sbas_Telemetry_Data::decode_sbstype6(const sbsmsg_t *msg, sbssat_t *sbssat)
|
|||||||
int Sbas_Telemetry_Data::decode_sbstype7(const sbsmsg_t *msg, sbssat_t *sbssat)
|
int Sbas_Telemetry_Data::decode_sbstype7(const sbsmsg_t *msg, sbssat_t *sbssat)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
trace(4,"decode_sbstype7");
|
trace(4,"decode_sbstype7");
|
||||||
|
if (sbssat->iodp != (int)getbitu(msg->msg, 18, 2)) return 0;
|
||||||
if (sbssat->iodp!=(int)getbitu(msg->msg,18,2)) return 0;
|
sbssat->tlat = getbitu(msg->msg, 14, 4);
|
||||||
|
|
||||||
sbssat->tlat = getbitu(msg->msg,14,4);
|
|
||||||
|
|
||||||
for (i=0; i < sbssat->nsat && i < MAXSAT; i++)
|
for (i=0; i < sbssat->nsat && i < MAXSAT; i++)
|
||||||
{
|
{
|
||||||
sbssat->sat[i].fcorr.ai = getbitu(msg->msg, 22 + i*4, 4);
|
sbssat->sat[i].fcorr.ai = getbitu(msg->msg, 22 + i*4, 4);
|
||||||
@ -700,7 +678,7 @@ int Sbas_Telemetry_Data::decode_sbstype7(const sbsmsg_t *msg, sbssat_t *sbssat)
|
|||||||
/* decode type 9: geo navigation message -------------------------------------*/
|
/* decode type 9: geo navigation message -------------------------------------*/
|
||||||
int Sbas_Telemetry_Data::decode_sbstype9(const sbsmsg_t *msg, nav_t *nav)
|
int Sbas_Telemetry_Data::decode_sbstype9(const sbsmsg_t *msg, nav_t *nav)
|
||||||
{
|
{
|
||||||
seph_t seph={0};
|
seph_t seph = {0};
|
||||||
int i;
|
int i;
|
||||||
int sat;
|
int sat;
|
||||||
|
|
||||||
@ -719,17 +697,17 @@ int Sbas_Telemetry_Data::decode_sbstype9(const sbsmsg_t *msg, nav_t *nav)
|
|||||||
seph.t0 = getbitu(msg->msg, 22, 13)*16;
|
seph.t0 = getbitu(msg->msg, 22, 13)*16;
|
||||||
seph.tof = msg->sample_stamp;
|
seph.tof = msg->sample_stamp;
|
||||||
seph.sva = getbitu(msg->msg, 35, 4);
|
seph.sva = getbitu(msg->msg, 35, 4);
|
||||||
seph.svh = seph.sva==15?1:0; /* unhealthy if ura==15 */
|
seph.svh = seph.sva == 15 ? 1 : 0; /* unhealthy if ura==15 */
|
||||||
|
|
||||||
seph.pos[0] = getbits(msg->msg, 39,30)*0.08;
|
seph.pos[0] = getbits(msg->msg, 39, 30)*0.08;
|
||||||
seph.pos[1] = getbits(msg->msg, 69,30)*0.08;
|
seph.pos[1] = getbits(msg->msg, 69, 30)*0.08;
|
||||||
seph.pos[2] = getbits(msg->msg, 99,25)*0.4;
|
seph.pos[2] = getbits(msg->msg, 99, 25)*0.4;
|
||||||
seph.vel[0] = getbits(msg->msg,124,17)*0.000625;
|
seph.vel[0] = getbits(msg->msg, 124, 17)*0.000625;
|
||||||
seph.vel[1] = getbits(msg->msg,141,17)*0.000625;
|
seph.vel[1] = getbits(msg->msg, 141, 17)*0.000625;
|
||||||
seph.vel[2] = getbits(msg->msg,158,18)*0.004;
|
seph.vel[2] = getbits(msg->msg, 158, 18)*0.004;
|
||||||
seph.acc[0] = getbits(msg->msg,176,10)*0.0000125;
|
seph.acc[0] = getbits(msg->msg, 176, 10)*0.0000125;
|
||||||
seph.acc[1] = getbits(msg->msg,186,10)*0.0000125;
|
seph.acc[1] = getbits(msg->msg, 186, 10)*0.0000125;
|
||||||
seph.acc[2] = getbits(msg->msg,196,10)*0.0000625;
|
seph.acc[2] = getbits(msg->msg, 196, 10)*0.0000625;
|
||||||
|
|
||||||
seph.af0 = getbits(msg->msg, 206, 12)*P2_31;
|
seph.af0 = getbits(msg->msg, 206, 12)*P2_31;
|
||||||
seph.af1 = getbits(msg->msg, 218, 8)*P2_39/2.0;
|
seph.af1 = getbits(msg->msg, 218, 8)*P2_39/2.0;
|
||||||
@ -740,8 +718,8 @@ int Sbas_Telemetry_Data::decode_sbstype9(const sbsmsg_t *msg, nav_t *nav)
|
|||||||
VLOG(FLOW) << "<<T>> no change in ephemeris -> won't parse";
|
VLOG(FLOW) << "<<T>> no change in ephemeris -> won't parse";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
nav->seph[NSATSBS+i] = nav->seph[i]; /* previous */
|
nav->seph[NSATSBS + i] = nav->seph[i]; /* previous */
|
||||||
nav->seph[i] = seph; /* current */
|
nav->seph[i] = seph; /* current */
|
||||||
|
|
||||||
trace(5, "decode_sbstype9: prn=%d", msg->prn);
|
trace(5, "decode_sbstype9: prn=%d", msg->prn);
|
||||||
return 1;
|
return 1;
|
||||||
@ -761,9 +739,10 @@ int Sbas_Telemetry_Data::decode_sbstype18(const sbsmsg_t *msg, sbsion_t *sbsion)
|
|||||||
else if (9 <= band && band <= 10) {p = igpband2[band - 9]; m = 5;}
|
else if (9 <= band && band <= 10) {p = igpband2[band - 9]; m = 5;}
|
||||||
else return 0;
|
else return 0;
|
||||||
|
|
||||||
short iodi_new = (short)getbitu(msg->msg,22,2);
|
short iodi_new = (short)getbitu(msg->msg, 22, 2);
|
||||||
if(sbsion[band].iodi != iodi_new)
|
if(sbsion[band].iodi != iodi_new)
|
||||||
{// IGP mask changed -> invalidate all IGPs in this band
|
{
|
||||||
|
// IGP mask changed -> invalidate all IGPs in this band
|
||||||
igp_mask_changed(band);
|
igp_mask_changed(band);
|
||||||
}
|
}
|
||||||
sbsion[band].iodi = iodi_new;
|
sbsion[band].iodi = iodi_new;
|
||||||
@ -773,9 +752,9 @@ int Sbas_Telemetry_Data::decode_sbstype18(const sbsmsg_t *msg, sbsion_t *sbsion)
|
|||||||
if (!getbitu(msg->msg, 23+i, 1)) continue;
|
if (!getbitu(msg->msg, 23+i, 1)) continue;
|
||||||
for (j=0; j<m; j++)
|
for (j=0; j<m; j++)
|
||||||
{
|
{
|
||||||
if (i<p[j].bits||p[j].bite<i) continue;
|
if (i < p[j].bits || p[j].bite < i) continue;
|
||||||
sbsion[band].igp[n].lat = band <= 8?p[j].y[i-p[j].bits]:p[j].x;
|
sbsion[band].igp[n].lat = band <= 8 ? p[j].y[i - p[j].bits] : p[j].x;
|
||||||
sbsion[band].igp[n++].lon = band <= 8?p[j].x:p[j].y[i-p[j].bits];
|
sbsion[band].igp[n++].lon = band <= 8 ? p[j].x : p[j].y[i - p[j].bits];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -791,27 +770,27 @@ int Sbas_Telemetry_Data::decode_sbstype18(const sbsmsg_t *msg, sbsion_t *sbsion)
|
|||||||
/* decode half long term correction (vel code=0) -----------------------------*/
|
/* decode half long term correction (vel code=0) -----------------------------*/
|
||||||
int Sbas_Telemetry_Data::decode_longcorr0(const sbsmsg_t *msg, int p, sbssat_t *sbssat)
|
int Sbas_Telemetry_Data::decode_longcorr0(const sbsmsg_t *msg, int p, sbssat_t *sbssat)
|
||||||
{
|
{
|
||||||
int i,n = getbitu(msg->msg, p, 6);
|
int i, n = getbitu(msg->msg, p, 6);
|
||||||
|
|
||||||
trace(4, "decode_longcorr0:");
|
trace(4, "decode_longcorr0:");
|
||||||
|
|
||||||
if (n==0 || n>MAXSAT) return 0;
|
if (n == 0 || n > MAXSAT) return 0;
|
||||||
|
|
||||||
sbssat->sat[n-1].lcorr.iode = getbitu(msg->msg, p+6, 8);
|
sbssat->sat[n - 1].lcorr.iode = getbitu(msg->msg, p + 6, 8);
|
||||||
|
|
||||||
for (i=0;i<3;i++)
|
for (i=0; i<3; i++)
|
||||||
{
|
{
|
||||||
sbssat->sat[n-1].lcorr.dpos[i] = getbits(msg->msg, p + 14 + 9*i, 9)*0.125;
|
sbssat->sat[n - 1].lcorr.dpos[i] = getbits(msg->msg, p + 14 + 9*i, 9)*0.125;
|
||||||
sbssat->sat[n-1].lcorr.dvel[i] = 0.0;
|
sbssat->sat[n - 1].lcorr.dvel[i] = 0.0;
|
||||||
}
|
}
|
||||||
sbssat->sat[n-1].lcorr.daf0 = getbits(msg->msg,p+41,10)*P2_31;
|
sbssat->sat[n - 1].lcorr.daf0 = getbits(msg->msg, p + 41, 10)*P2_31;
|
||||||
sbssat->sat[n-1].lcorr.daf1 = 0.0;
|
sbssat->sat[n - 1].lcorr.daf1 = 0.0;
|
||||||
//sbssat->sat[n-1].lcorr.t0=gpst2time(msg->week,msg->tow);
|
//sbssat->sat[n-1].lcorr.t0=gpst2time(msg->week,msg->tow);
|
||||||
sbssat->sat[n-1].lcorr.trx = msg->sample_stamp; // vel=0 -> time of applicability is reception time
|
sbssat->sat[n - 1].lcorr.trx = msg->sample_stamp; // vel=0 -> time of applicability is reception time
|
||||||
sbssat->sat[n-1].lcorr.tapp = 0;
|
sbssat->sat[n - 1].lcorr.tapp = 0;
|
||||||
sbssat->sat[n-1].lcorr.valid = true;
|
sbssat->sat[n - 1].lcorr.valid = true;
|
||||||
|
|
||||||
trace(5, "decode_longcorr0:sat=%2d", sbssat->sat[n-1].sat);
|
trace(5, "decode_longcorr0:sat=%2d", sbssat->sat[n - 1].sat);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -827,25 +806,25 @@ int Sbas_Telemetry_Data::decode_longcorr1(const sbsmsg_t *msg, int p, sbssat_t *
|
|||||||
|
|
||||||
if (n==0 || n>MAXSAT) return 0;
|
if (n==0 || n>MAXSAT) return 0;
|
||||||
|
|
||||||
sbssat->sat[n-1].lcorr.iode = getbitu(msg->msg, p + 6,8);
|
sbssat->sat[n - 1].lcorr.iode = getbitu(msg->msg, p + 6, 8);
|
||||||
|
|
||||||
for (i=0; i<3; i++)
|
for (i=0; i<3; i++)
|
||||||
{
|
{
|
||||||
sbssat->sat[n-1].lcorr.dpos[i] = getbits(msg->msg, p + 14 +i*11, 11)*0.125;
|
sbssat->sat[n - 1].lcorr.dpos[i] = getbits(msg->msg, p + 14 + i*11, 11)*0.125;
|
||||||
sbssat->sat[n-1].lcorr.dvel[i] = getbits(msg->msg, p + 58 +i* 8, 8)*P2_11;
|
sbssat->sat[n - 1].lcorr.dvel[i] = getbits(msg->msg, p + 58 + i*8, 8)*P2_11;
|
||||||
}
|
}
|
||||||
sbssat->sat[n-1].lcorr.daf0 = getbits(msg->msg, p + 47, 11)*P2_31;
|
sbssat->sat[n - 1].lcorr.daf0 = getbits(msg->msg, p + 47, 11)*P2_31;
|
||||||
sbssat->sat[n-1].lcorr.daf1 = getbits(msg->msg, p + 82, 8)*P2_39;
|
sbssat->sat[n - 1].lcorr.daf1 = getbits(msg->msg, p + 82, 8)*P2_39;
|
||||||
// vel=1 -> time of applicability is sent in message, needs to be corrected for rollover which can not be done here, since the absolute gps time is unknown. see IS-GPS-200G pdf page 116 for correction
|
// vel=1 -> time of applicability is sent in message, needs to be corrected for rollover which can not be done here, since the absolute gps time is unknown. see IS-GPS-200G pdf page 116 for correction
|
||||||
/*t=(int)getbitu(msg->msg,p+90,13)*16-(int)msg->tow%86400;
|
/*t=(int)getbitu(msg->msg,p+90,13)*16-(int)msg->tow%86400;
|
||||||
if (t<=-43200) t+=86400;
|
if (t<=-43200) t+=86400;
|
||||||
else if (t> 43200) t-=86400;
|
else if (t> 43200) t-=86400;
|
||||||
sbssat->sat[n-1].lcorr.t0=gpst2time(msg->week,msg->tow+t);*/
|
sbssat->sat[n-1].lcorr.t0=gpst2time(msg->week,msg->tow+t);*/
|
||||||
sbssat->sat[n-1].lcorr.trx = msg->sample_stamp;
|
sbssat->sat[n - 1].lcorr.trx = msg->sample_stamp;
|
||||||
sbssat->sat[n-1].lcorr.tapp = (int)getbitu(msg->msg, p + 90, 13)*16;
|
sbssat->sat[n - 1].lcorr.tapp = (int)getbitu(msg->msg, p + 90, 13)*16;
|
||||||
sbssat->sat[n-1].lcorr.vel = 1;
|
sbssat->sat[n - 1].lcorr.vel = 1;
|
||||||
sbssat->sat[n-1].lcorr.valid = true;
|
sbssat->sat[n - 1].lcorr.valid = true;
|
||||||
trace(5, "decode_longcorr1: sat=%2d", sbssat->sat[n-1].sat);
|
trace(5, "decode_longcorr1: sat=%2d", sbssat->sat[n - 1].sat);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -858,15 +837,16 @@ int Sbas_Telemetry_Data::decode_longcorrh(const sbsmsg_t *msg, int p, sbssat_t *
|
|||||||
trace(4,"decode_longcorrh:");
|
trace(4,"decode_longcorrh:");
|
||||||
|
|
||||||
if (getbitu(msg->msg, p, 1) == 0 )
|
if (getbitu(msg->msg, p, 1) == 0 )
|
||||||
{ /* vel code=0 */
|
{
|
||||||
|
/* vel code=0 */
|
||||||
if (sbssat->iodp == (int)getbitu(msg->msg, p + 103, 2))
|
if (sbssat->iodp == (int)getbitu(msg->msg, p + 103, 2))
|
||||||
{
|
{
|
||||||
return decode_longcorr0(msg ,p+ 1,sbssat) && decode_longcorr0(msg, p + 52, sbssat);
|
return decode_longcorr0(msg, p + 1, sbssat) && decode_longcorr0(msg, p + 52, sbssat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sbssat->iodp == (int)getbitu(msg->msg, p + 104, 2))
|
else if (sbssat->iodp == (int)getbitu(msg->msg, p + 104, 2))
|
||||||
{
|
{
|
||||||
return decode_longcorr1(msg, p+1, sbssat);
|
return decode_longcorr1(msg, p + 1, sbssat);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -894,7 +874,7 @@ int Sbas_Telemetry_Data::decode_sbstype24(const sbsmsg_t *msg, sbssat_t *sbssat)
|
|||||||
//sbssat->sat[j].fcorr.t0 =gpst2time(msg->week,msg->tow);
|
//sbssat->sat[j].fcorr.t0 =gpst2time(msg->week,msg->tow);
|
||||||
sbssat->sat[j].fcorr.t0 = msg->sample_stamp;
|
sbssat->sat[j].fcorr.t0 = msg->sample_stamp;
|
||||||
sbssat->sat[j].fcorr.prc = getbits(msg->msg, 14 + i*12, 12)*0.125f;
|
sbssat->sat[j].fcorr.prc = getbits(msg->msg, 14 + i*12, 12)*0.125f;
|
||||||
sbssat->sat[j].fcorr.udre = udre+1;
|
sbssat->sat[j].fcorr.udre = udre + 1;
|
||||||
sbssat->sat[j].fcorr.iodf = iodf;
|
sbssat->sat[j].fcorr.iodf = iodf;
|
||||||
}
|
}
|
||||||
return decode_longcorrh(msg, 120, sbssat);
|
return decode_longcorrh(msg, 120, sbssat);
|
||||||
@ -908,7 +888,7 @@ int Sbas_Telemetry_Data::decode_sbstype25(const sbsmsg_t *msg, sbssat_t *sbssat)
|
|||||||
{
|
{
|
||||||
trace(4,"decode_sbstype25:");
|
trace(4,"decode_sbstype25:");
|
||||||
|
|
||||||
return decode_longcorrh(msg,14,sbssat)&&decode_longcorrh(msg,120,sbssat);
|
return decode_longcorrh(msg, 14, sbssat) && decode_longcorrh(msg, 120, sbssat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -925,13 +905,13 @@ int Sbas_Telemetry_Data::decode_sbstype26(const sbsmsg_t *msg, sbsion_t *sbsion)
|
|||||||
|
|
||||||
for (i=0; i<15; i++)
|
for (i=0; i<15; i++)
|
||||||
{
|
{
|
||||||
if ((j = block*15+i) >= sbsion[band].nigp) continue;
|
if ((j = block*15 + i) >= sbsion[band].nigp) continue;
|
||||||
give = getbitu(msg->msg, 2 + i*13 + 9, 4);
|
give = getbitu(msg->msg, 2 + i*13 + 9, 4);
|
||||||
delay = getbitu(msg->msg, 22 + i*13, 9);
|
delay = getbitu(msg->msg, 22 + i*13, 9);
|
||||||
//sbsion[band].igp[j].t0=gpst2time(msg->week,msg->tow);
|
//sbsion[band].igp[j].t0=gpst2time(msg->week,msg->tow);
|
||||||
sbsion[band].igp[j].t0 = msg->sample_stamp;
|
sbsion[band].igp[j].t0 = msg->sample_stamp;
|
||||||
sbsion[band].igp[j].valid = true;
|
sbsion[band].igp[j].valid = true;
|
||||||
sbsion[band].igp[j].delay = delay == 0x1FF?0.0f:delay*0.125f;
|
sbsion[band].igp[j].delay = delay == 0x1FF ? 0.0f : delay*0.125f;
|
||||||
sbsion[band].igp[j].give = give;
|
sbsion[band].igp[j].give = give;
|
||||||
|
|
||||||
if(sbsion[band].igp[j].give > 15) sbsion[band].igp[j].give = 15; // give is not higher than 15, but to be sure
|
if(sbsion[band].igp[j].give > 15) sbsion[band].igp[j].give = 15; // give is not higher than 15, but to be sure
|
||||||
@ -955,7 +935,7 @@ int Sbas_Telemetry_Data::decode_sbstype26(const sbsmsg_t *msg, sbsion_t *sbsion)
|
|||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
int Sbas_Telemetry_Data::sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav)
|
int Sbas_Telemetry_Data::sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav)
|
||||||
{
|
{
|
||||||
int type=getbitu(msg->msg,8,6),stat=-1;
|
int type = getbitu(msg->msg, 8, 6), stat = -1;
|
||||||
|
|
||||||
trace(3,"sbsupdatecorr: type=%d",type);
|
trace(3,"sbsupdatecorr: type=%d",type);
|
||||||
|
|
||||||
@ -963,15 +943,15 @@ int Sbas_Telemetry_Data::sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav)
|
|||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 0: stat = decode_sbstype2 (msg, &nav->sbssat); break;
|
case 0: stat = decode_sbstype2(msg, &nav->sbssat); break;
|
||||||
case 1: stat = decode_sbstype1 (msg, &nav->sbssat); break;
|
case 1: stat = decode_sbstype1(msg, &nav->sbssat); break;
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
case 5: stat = decode_sbstype2 (msg, &nav->sbssat); break;
|
case 5: stat = decode_sbstype2(msg, &nav->sbssat); break;
|
||||||
case 6: stat = decode_sbstype6 (msg, &nav->sbssat); break;
|
case 6: stat = decode_sbstype6(msg, &nav->sbssat); break;
|
||||||
case 7: stat = decode_sbstype7 (msg, &nav->sbssat); break;
|
case 7: stat = decode_sbstype7(msg, &nav->sbssat); break;
|
||||||
case 9: stat = decode_sbstype9 (msg, nav); break;
|
case 9: stat = decode_sbstype9(msg, nav); break;
|
||||||
case 10: trace(2, "unsupported sbas message: type=%d", type); break;
|
case 10: trace(2, "unsupported sbas message: type=%d", type); break;
|
||||||
case 12: trace(2, "unsupported sbas message: type=%d", type); break;
|
case 12: trace(2, "unsupported sbas message: type=%d", type); break;
|
||||||
case 17: trace(2, "unsupported sbas message: type=%d", type); break;
|
case 17: trace(2, "unsupported sbas message: type=%d", type); break;
|
||||||
@ -981,11 +961,12 @@ int Sbas_Telemetry_Data::sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav)
|
|||||||
case 26: stat = decode_sbstype26(msg, nav ->sbsion); break;
|
case 26: stat = decode_sbstype26(msg, nav ->sbsion); break;
|
||||||
case 63: break; /* null message */
|
case 63: break; /* null message */
|
||||||
|
|
||||||
default: trace(2,"unsupported sbas message: type=%d",type); break;
|
default: trace(2, "Unsupported SBAS message: type=%d", type); break;
|
||||||
}
|
}
|
||||||
return stat?type:-1;
|
return stat ? type : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Sbas_Telemetry_Data::prn_mask_changed()
|
void Sbas_Telemetry_Data::prn_mask_changed()
|
||||||
{
|
{
|
||||||
d_nav.sbssat.tlat = -1;
|
d_nav.sbssat.tlat = -1;
|
||||||
@ -997,6 +978,7 @@ void Sbas_Telemetry_Data::prn_mask_changed()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Sbas_Telemetry_Data::is_rtklib_sat_correction_valid(int sat)
|
bool Sbas_Telemetry_Data::is_rtklib_sat_correction_valid(int sat)
|
||||||
{
|
{
|
||||||
return d_nav.sbssat.tlat > -1
|
return d_nav.sbssat.tlat > -1
|
||||||
@ -1004,6 +986,7 @@ bool Sbas_Telemetry_Data::is_rtklib_sat_correction_valid(int sat)
|
|||||||
&& d_nav.sbssat.sat[sat].lcorr.valid;
|
&& d_nav.sbssat.sat[sat].lcorr.valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Sbas_Telemetry_Data::igp_mask_changed(int band)
|
void Sbas_Telemetry_Data::igp_mask_changed(int band)
|
||||||
{
|
{
|
||||||
for(int i_igp = 0; i_igp < d_nav.sbsion[band].nigp; i_igp++)
|
for(int i_igp = 0; i_igp < d_nav.sbsion[band].nigp; i_igp++)
|
||||||
|
@ -54,8 +54,8 @@ struct Long_Term_Correction;
|
|||||||
class Sbas_Ephemeris;
|
class Sbas_Ephemeris;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* \brief represents a raw SBAS message of 250bits + 6bits padding
|
* \brief Represents a raw SBAS message of 250cbits + 6 bits padding
|
||||||
* (8b preamble + 6b message type + 212b data + 24b CRC + 6b zerro padding)
|
* (8b preamble + 6b message type + 212b data + 24b CRC + 6b zero padding)
|
||||||
*/
|
*/
|
||||||
class Sbas_Raw_Msg
|
class Sbas_Raw_Msg
|
||||||
{
|
{
|
||||||
@ -90,425 +90,416 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//int d_week; /* reception time */
|
//int d_week; /* reception time */
|
||||||
//int d_tow; /* reception time */
|
//int d_tow; /* reception time */
|
||||||
Sbas_Time rx_time;
|
Sbas_Time rx_time;
|
||||||
int i_prn; /* SBAS satellite PRN number */
|
int i_prn; /* SBAS satellite PRN number */
|
||||||
std::vector<unsigned char> d_msg; /* SBAS message (226bit) padded by 0 */
|
std::vector<unsigned char> d_msg; /* SBAS message (226 bit) padded by 0 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* \brief holds an updated set of the telemetry data received from SBAS
|
* \brief Holds an updated set of the telemetry data received from SBAS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Sbas_Telemetry_Data
|
class Sbas_Telemetry_Data
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
int update(Sbas_Raw_Msg sbas_raw_msg);
|
||||||
int
|
void set_raw_msg_queue(concurrent_queue<Sbas_Raw_Msg> *raw_msg_queue);
|
||||||
update(Sbas_Raw_Msg sbas_raw_msg);
|
void set_iono_queue(concurrent_queue<Sbas_Ionosphere_Correction> *iono_queue);
|
||||||
|
void set_sat_corr_queue(concurrent_queue<Sbas_Satellite_Correction> *sat_corr_queue);
|
||||||
void
|
void set_ephemeris_queue(concurrent_queue<Sbas_Ephemeris> *ephemeris_queue);
|
||||||
set_raw_msg_queue(concurrent_queue<Sbas_Raw_Msg> *raw_msg_queue);
|
|
||||||
void
|
|
||||||
set_iono_queue(concurrent_queue<Sbas_Ionosphere_Correction> *iono_queue);
|
|
||||||
void
|
|
||||||
set_sat_corr_queue(concurrent_queue<Sbas_Satellite_Correction> *sat_corr_queue);
|
|
||||||
void
|
|
||||||
set_ephemeris_queue(concurrent_queue<Sbas_Ephemeris> *ephemeris_queue);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Default constructor
|
* Default constructor
|
||||||
*/
|
*/
|
||||||
Sbas_Telemetry_Data();
|
Sbas_Telemetry_Data();
|
||||||
/*!
|
/*!
|
||||||
* Default deconstructor
|
* Default deconstructor
|
||||||
*/
|
*/
|
||||||
~Sbas_Telemetry_Data();
|
~Sbas_Telemetry_Data();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<int, Fast_Correction> emitted_fast_corrections;
|
std::map<int, Fast_Correction> emitted_fast_corrections;
|
||||||
std::map<int, Long_Term_Correction> emitted_long_term_corrections;
|
std::map<int, Long_Term_Correction> emitted_long_term_corrections;
|
||||||
|
|
||||||
Sbas_Time_Relation mt12_time_ref;
|
Sbas_Time_Relation mt12_time_ref;
|
||||||
|
|
||||||
concurrent_queue<Sbas_Raw_Msg> *raw_msg_queue;
|
concurrent_queue<Sbas_Raw_Msg> *raw_msg_queue;
|
||||||
concurrent_queue<Sbas_Ionosphere_Correction> *iono_queue;
|
concurrent_queue<Sbas_Ionosphere_Correction> *iono_queue;
|
||||||
concurrent_queue<Sbas_Satellite_Correction> *sat_corr_queue;
|
concurrent_queue<Sbas_Satellite_Correction> *sat_corr_queue;
|
||||||
concurrent_queue<Sbas_Ephemeris> *ephemeris_queue;
|
concurrent_queue<Sbas_Ephemeris> *ephemeris_queue;
|
||||||
|
|
||||||
int decode_mt12(Sbas_Raw_Msg sbas_raw_msg);
|
int decode_mt12(Sbas_Raw_Msg sbas_raw_msg);
|
||||||
|
|
||||||
void updated_sbas_ephemeris(Sbas_Raw_Msg msg);
|
void updated_sbas_ephemeris(Sbas_Raw_Msg msg);
|
||||||
void received_iono_correction();
|
void received_iono_correction();
|
||||||
void updated_satellite_corrections();
|
void updated_satellite_corrections();
|
||||||
|
|
||||||
/////// rtklib.h
|
/////// rtklib.h
|
||||||
|
|
||||||
#define SYS_NONE 0x00 /* navigation system: none */
|
#define SYS_NONE 0x00 /* navigation system: none */
|
||||||
#define SYS_GPS 0x01 /* navigation system: GPS */
|
#define SYS_GPS 0x01 /* navigation system: GPS */
|
||||||
#define SYS_SBS 0x02 /* navigation system: SBAS */
|
#define SYS_SBS 0x02 /* navigation system: SBAS */
|
||||||
#define SYS_GLO 0x04 /* navigation system: GLONASS */
|
#define SYS_GLO 0x04 /* navigation system: GLONASS */
|
||||||
#define SYS_GAL 0x08 /* navigation system: Galileo */
|
#define SYS_GAL 0x08 /* navigation system: Galileo */
|
||||||
#define SYS_QZS 0x10 /* navigation system: QZSS */
|
#define SYS_QZS 0x10 /* navigation system: QZSS */
|
||||||
#define SYS_CMP 0x20 /* navigation system: BeiDou */
|
#define SYS_CMP 0x20 /* navigation system: BeiDou */
|
||||||
#define SYS_ALL 0xFF /* navigation system: all */
|
#define SYS_ALL 0xFF /* navigation system: all */
|
||||||
|
|
||||||
#define TSYS_GPS 0 /* time system: GPS time */
|
#define TSYS_GPS 0 /* time system: GPS time */
|
||||||
#define TSYS_UTC 1 /* time system: UTC */
|
#define TSYS_UTC 1 /* time system: UTC */
|
||||||
#define TSYS_GLO 2 /* time system: GLONASS time */
|
#define TSYS_GLO 2 /* time system: GLONASS time */
|
||||||
#define TSYS_GAL 3 /* time system: Galileo time */
|
#define TSYS_GAL 3 /* time system: Galileo time */
|
||||||
#define TSYS_QZS 4 /* time system: QZSS time */
|
#define TSYS_QZS 4 /* time system: QZSS time */
|
||||||
#define TSYS_CMP 5 /* time system: BeiDou time */
|
#define TSYS_CMP 5 /* time system: BeiDou time */
|
||||||
|
|
||||||
#ifndef NFREQ
|
#ifndef NFREQ
|
||||||
#define NFREQ 3 /* number of carrier frequencies */
|
#define NFREQ 3 /* number of carrier frequencies */
|
||||||
#endif
|
#endif
|
||||||
#define NFREQGLO 2 /* number of carrier frequencies of GLONASS */
|
#define NFREQGLO 2 /* number of carrier frequencies of GLONASS */
|
||||||
|
|
||||||
#ifndef NEXOBS
|
#ifndef NEXOBS
|
||||||
#define NEXOBS 0 /* number of extended obs codes */
|
#define NEXOBS 0 /* number of extended obs codes */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MINPRNGPS 1 /* min satellite PRN number of GPS */
|
#define MINPRNGPS 1 /* min satellite PRN number of GPS */
|
||||||
#define MAXPRNGPS 32 /* max satellite PRN number of GPS */
|
#define MAXPRNGPS 32 /* max satellite PRN number of GPS */
|
||||||
#define NSATGPS (MAXPRNGPS-MINPRNGPS+1) /* number of GPS satellites */
|
#define NSATGPS (MAXPRNGPS-MINPRNGPS+1) /* number of GPS satellites */
|
||||||
#define NSYSGPS 1
|
#define NSYSGPS 1
|
||||||
|
|
||||||
#ifdef ENAGLO
|
#ifdef ENAGLO
|
||||||
#define MINPRNGLO 1 /* min satellite slot number of GLONASS */
|
#define MINPRNGLO 1 /* min satellite slot number of GLONASS */
|
||||||
#define MAXPRNGLO 24 /* max satellite slot number of GLONASS */
|
#define MAXPRNGLO 24 /* max satellite slot number of GLONASS */
|
||||||
#define NSATGLO (MAXPRNGLO-MINPRNGLO+1) /* number of GLONASS satellites */
|
#define NSATGLO (MAXPRNGLO-MINPRNGLO+1) /* number of GLONASS satellites */
|
||||||
#define NSYSGLO 1
|
#define NSYSGLO 1
|
||||||
#else
|
#else
|
||||||
#define MINPRNGLO 0
|
#define MINPRNGLO 0
|
||||||
#define MAXPRNGLO 0
|
#define MAXPRNGLO 0
|
||||||
#define NSATGLO 0
|
#define NSATGLO 0
|
||||||
#define NSYSGLO 0
|
#define NSYSGLO 0
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENAGAL
|
#ifdef ENAGAL
|
||||||
#define MINPRNGAL 1 /* min satellite PRN number of Galileo */
|
#define MINPRNGAL 1 /* min satellite PRN number of Galileo */
|
||||||
#define MAXPRNGAL 27 /* max satellite PRN number of Galileo */
|
#define MAXPRNGAL 27 /* max satellite PRN number of Galileo */
|
||||||
#define NSATGAL (MAXPRNGAL-MINPRNGAL+1) /* number of Galileo satellites */
|
#define NSATGAL (MAXPRNGAL-MINPRNGAL+1) /* number of Galileo satellites */
|
||||||
#define NSYSGAL 1
|
#define NSYSGAL 1
|
||||||
#else
|
#else
|
||||||
#define MINPRNGAL 0
|
#define MINPRNGAL 0
|
||||||
#define MAXPRNGAL 0
|
#define MAXPRNGAL 0
|
||||||
#define NSATGAL 0
|
#define NSATGAL 0
|
||||||
#define NSYSGAL 0
|
#define NSYSGAL 0
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENAQZS
|
#ifdef ENAQZS
|
||||||
#define MINPRNQZS 193 /* min satellite PRN number of QZSS */
|
#define MINPRNQZS 193 /* min satellite PRN number of QZSS */
|
||||||
#define MAXPRNQZS 195 /* max satellite PRN number of QZSS */
|
#define MAXPRNQZS 195 /* max satellite PRN number of QZSS */
|
||||||
#define MINPRNQZS_S 183 /* min satellite PRN number of QZSS SAIF */
|
#define MINPRNQZS_S 183 /* min satellite PRN number of QZSS SAIF */
|
||||||
#define MAXPRNQZS_S 185 /* max satellite PRN number of QZSS SAIF */
|
#define MAXPRNQZS_S 185 /* max satellite PRN number of QZSS SAIF */
|
||||||
#define NSATQZS (MAXPRNQZS-MINPRNQZS+1) /* number of QZSS satellites */
|
#define NSATQZS (MAXPRNQZS-MINPRNQZS+1) /* number of QZSS satellites */
|
||||||
#define NSYSQZS 1
|
#define NSYSQZS 1
|
||||||
#else
|
#else
|
||||||
#define MINPRNQZS 0
|
#define MINPRNQZS 0
|
||||||
#define MAXPRNQZS 0
|
#define MAXPRNQZS 0
|
||||||
#define NSATQZS 0
|
#define NSATQZS 0
|
||||||
#define NSYSQZS 0
|
#define NSYSQZS 0
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENACMP
|
#ifdef ENACMP
|
||||||
#define MINPRNCMP 1 /* min satellite sat number of BeiDou */
|
#define MINPRNCMP 1 /* min satellite sat number of BeiDou */
|
||||||
#define MAXPRNCMP 35 /* max satellite sat number of BeiDou */
|
#define MAXPRNCMP 35 /* max satellite sat number of BeiDou */
|
||||||
#define NSATCMP (MAXPRNCMP-MINPRNCMP+1) /* number of BeiDou satellites */
|
#define NSATCMP (MAXPRNCMP-MINPRNCMP+1) /* number of BeiDou satellites */
|
||||||
#define NSYSCMP 1
|
#define NSYSCMP 1
|
||||||
#else
|
#else
|
||||||
#define MINPRNCMP 0
|
#define MINPRNCMP 0
|
||||||
#define MAXPRNCMP 0
|
#define MAXPRNCMP 0
|
||||||
#define NSATCMP 0
|
#define NSATCMP 0
|
||||||
#define NSYSCMP 0
|
#define NSYSCMP 0
|
||||||
#endif
|
#endif
|
||||||
#define NSYS (NSYSGPS+NSYSGLO+NSYSGAL+NSYSQZS+NSYSCMP) /* number of systems */
|
#define NSYS (NSYSGPS+NSYSGLO+NSYSGAL+NSYSQZS+NSYSCMP) /* number of systems */
|
||||||
|
|
||||||
#define MINPRNSBS 120 /* min satellite PRN number of SBAS */
|
#define MINPRNSBS 120 /* min satellite PRN number of SBAS */
|
||||||
#define MAXPRNSBS 142 /* max satellite PRN number of SBAS */
|
#define MAXPRNSBS 142 /* max satellite PRN number of SBAS */
|
||||||
#define NSATSBS (MAXPRNSBS-MINPRNSBS+1) /* number of SBAS satellites */
|
#define NSATSBS (MAXPRNSBS-MINPRNSBS+1) /* number of SBAS satellites */
|
||||||
|
|
||||||
#define MAXSAT (NSATGPS+NSATGLO+NSATGAL+NSATQZS+NSATCMP+NSATSBS)
|
#define MAXSAT (NSATGPS+NSATGLO+NSATGAL+NSATQZS+NSATCMP+NSATSBS)
|
||||||
/* max satellite number (1 to MAXSAT) */
|
/* max satellite number (1 to MAXSAT) */
|
||||||
#ifndef MAXOBS
|
#ifndef MAXOBS
|
||||||
#define MAXOBS 64 /* max number of obs in an epoch */
|
#define MAXOBS 64 /* max number of obs in an epoch */
|
||||||
#endif
|
#endif
|
||||||
#define MAXRCV 64 /* max receiver number (1 to MAXRCV) */
|
#define MAXRCV 64 /* max receiver number (1 to MAXRCV) */
|
||||||
#define MAXOBSTYPE 64 /* max number of obs type in RINEX */
|
#define MAXOBSTYPE 64 /* max number of obs type in RINEX */
|
||||||
#define DTTOL 0.005 /* tolerance of time difference (s) */
|
#define DTTOL 0.005 /* tolerance of time difference (s) */
|
||||||
#if 0
|
#if 0
|
||||||
#define MAXDTOE 10800.0 /* max time difference to ephem Toe (s) for GPS */
|
#define MAXDTOE 10800.0 /* max time difference to ephem Toe (s) for GPS */
|
||||||
#else
|
#else
|
||||||
#define MAXDTOE 7200.0 /* max time difference to ephem Toe (s) for GPS */
|
#define MAXDTOE 7200.0 /* max time difference to ephem Toe (s) for GPS */
|
||||||
#endif
|
#endif
|
||||||
#define MAXDTOE_GLO 1800.0 /* max time difference to GLONASS Toe (s) */
|
#define MAXDTOE_GLO 1800.0 /* max time difference to GLONASS Toe (s) */
|
||||||
#define MAXDTOE_SBS 360.0 /* max time difference to SBAS Toe (s) */
|
#define MAXDTOE_SBS 360.0 /* max time difference to SBAS Toe (s) */
|
||||||
#define MAXDTOE_S 86400.0 /* max time difference to ephem toe (s) for other */
|
#define MAXDTOE_S 86400.0 /* max time difference to ephem toe (s) for other */
|
||||||
#define MAXGDOP 300.0 /* max GDOP */
|
#define MAXGDOP 300.0 /* max GDOP */
|
||||||
|
|
||||||
//#define MAXSBSAGEF 30.0 /* max age of SBAS fast correction (s) */
|
//#define MAXSBSAGEF 30.0 /* max age of SBAS fast correction (s) */
|
||||||
//#define MAXSBSAGEL 1800.0 /* max age of SBAS long term corr (s) */
|
//#define MAXSBSAGEL 1800.0 /* max age of SBAS long term corr (s) */
|
||||||
//#define MAXSBSURA 8 /* max URA of SBAS satellite */
|
//#define MAXSBSURA 8 /* max URA of SBAS satellite */
|
||||||
#define MAXBAND 10 /* max SBAS band of IGP */
|
#define MAXBAND 10 /* max SBAS band of IGP */
|
||||||
#define MAXNIGP 201 /* max number of IGP in SBAS band */
|
#define MAXNIGP 201 /* max number of IGP in SBAS band */
|
||||||
//#define MAXNGEO 4 /* max number of GEO satellites */
|
//#define MAXNGEO 4 /* max number of GEO satellites */
|
||||||
|
|
||||||
|
|
||||||
#define P2_11 4.882812500000000E-04 /* 2^-11 */
|
#define P2_11 4.882812500000000E-04 /* 2^-11 */
|
||||||
#define P2_31 4.656612873077393E-10 /* 2^-31 */
|
#define P2_31 4.656612873077393E-10 /* 2^-31 */
|
||||||
#define P2_39 1.818989403545856E-12 /* 2^-39 */
|
#define P2_39 1.818989403545856E-12 /* 2^-39 */
|
||||||
|
|
||||||
/* type definitions ----------------------------------------------------------*/
|
/* type definitions ----------------------------------------------------------*/
|
||||||
|
|
||||||
typedef struct { /* time struct */
|
typedef struct { /* time struct */
|
||||||
time_t time; /* time (s) expressed by standard time_t */
|
time_t time; /* time (s) expressed by standard time_t */
|
||||||
double sec; /* fraction of second under 1 s */
|
double sec; /* fraction of second under 1 s */
|
||||||
} gtime_t;
|
} gtime_t;
|
||||||
|
|
||||||
typedef struct { /* SBAS message type */
|
typedef struct { /* SBAS message type */
|
||||||
//int week,tow; /* receiption time */
|
//int week,tow; /* receiption time */
|
||||||
double sample_stamp;
|
double sample_stamp;
|
||||||
int prn; /* SBAS satellite PRN number */
|
int prn; /* SBAS satellite PRN number */
|
||||||
unsigned char msg[29]; /* SBAS message (226bit) padded by 0 */
|
unsigned char msg[29]; /* SBAS message (226bit) padded by 0 */
|
||||||
} sbsmsg_t;
|
} sbsmsg_t;
|
||||||
|
|
||||||
typedef struct { /* SBAS messages type */
|
typedef struct { /* SBAS messages type */
|
||||||
int n,nmax; /* number of SBAS messages/allocated */
|
int n,nmax; /* number of SBAS messages/allocated */
|
||||||
sbsmsg_t *msgs; /* SBAS messages */
|
sbsmsg_t *msgs; /* SBAS messages */
|
||||||
} sbs_t;
|
} sbs_t;
|
||||||
|
|
||||||
typedef struct { /* SBAS fast correction type */
|
typedef struct { /* SBAS fast correction type */
|
||||||
//gtime_t t0; /* time of applicability (TOF) */
|
//gtime_t t0; /* time of applicability (TOF) */
|
||||||
double t0;
|
double t0;
|
||||||
bool valid;
|
bool valid;
|
||||||
double prc; /* pseudorange correction (PRC) (m) */
|
double prc; /* pseudorange correction (PRC) (m) */
|
||||||
double rrc; /* range-rate correction (RRC) (m/s) */
|
double rrc; /* range-rate correction (RRC) (m/s) */
|
||||||
double dt; /* range-rate correction delta-time (s) */
|
double dt; /* range-rate correction delta-time (s) */
|
||||||
int iodf; /* IODF (issue of date fast corr) */
|
int iodf; /* IODF (issue of date fast corr) */
|
||||||
short udre; /* UDRE+1 */
|
short udre; /* UDRE+1 */
|
||||||
short ai; /* degradation factor indicator */
|
short ai; /* degradation factor indicator */
|
||||||
} sbsfcorr_t;
|
} sbsfcorr_t;
|
||||||
|
|
||||||
typedef struct { /* SBAS long term satellite error correction type */
|
typedef struct { /* SBAS long term satellite error correction type */
|
||||||
//gtime_t t0; /* correction time */
|
//gtime_t t0; /* correction time */
|
||||||
double trx; // time when message was received
|
double trx; /* time when message was received */
|
||||||
int tapp; // time of applicability (when vel=1 sent as t0)
|
int tapp; /* time of applicability (when vel=1 sent as t0) */
|
||||||
int vel; // use velocity if vel=1
|
int vel; /* use velocity if vel=1 */
|
||||||
bool valid;
|
bool valid;
|
||||||
int iode; /* IODE (issue of date ephemeris) */
|
int iode; /* IODE (issue of date ephemeris) */
|
||||||
double dpos[3]; /* delta position (m) (ecef) */
|
double dpos[3]; /* delta position (m) (ecef) */
|
||||||
double dvel[3]; /* delta velocity (m/s) (ecef) */
|
double dvel[3]; /* delta velocity (m/s) (ecef) */
|
||||||
double daf0,daf1; /* delta clock-offset/drift (s,s/s) */
|
double daf0,daf1; /* delta clock-offset/drift (s,s/s) */
|
||||||
} sbslcorr_t;
|
} sbslcorr_t;
|
||||||
|
|
||||||
typedef struct { /* SBAS satellite correction type */
|
typedef struct { /* SBAS satellite correction type */
|
||||||
int sat; /* satellite number */
|
int sat; /* satellite number */
|
||||||
sbsfcorr_t fcorr; /* fast correction */
|
sbsfcorr_t fcorr; /* fast correction */
|
||||||
sbslcorr_t lcorr; /* long term correction */
|
sbslcorr_t lcorr; /* long term correction */
|
||||||
} sbssatp_t;
|
} sbssatp_t;
|
||||||
|
|
||||||
typedef struct { /* SBAS satellite corrections type */
|
typedef struct { /* SBAS satellite corrections type */
|
||||||
int iodp; /* IODP (issue of date mask) */
|
int iodp; /* IODP (issue of date mask) */
|
||||||
int nsat; /* number of satellites */
|
int nsat; /* number of satellites */
|
||||||
int tlat; /* system latency (s) */
|
int tlat; /* system latency (s) */
|
||||||
sbssatp_t sat[MAXSAT]; /* satellite correction */
|
sbssatp_t sat[MAXSAT]; /* satellite correction */
|
||||||
} sbssat_t;
|
} sbssat_t;
|
||||||
|
|
||||||
typedef struct { /* SBAS ionospheric correction type */
|
typedef struct { /* SBAS ionospheric correction type */
|
||||||
//gtime_t t0; /* correction time */
|
//gtime_t t0; /* correction time */
|
||||||
double t0;
|
double t0;
|
||||||
bool valid;
|
bool valid;
|
||||||
short lat,lon; /* latitude/longitude (deg) */
|
short lat,lon; /* latitude/longitude (deg) */
|
||||||
short give; /* GIVI+1 */
|
short give; /* GIVI+1 */
|
||||||
float delay; /* vertical delay estimate (m) */
|
float delay; /* vertical delay estimate (m) */
|
||||||
} sbsigp_t;
|
} sbsigp_t;
|
||||||
|
|
||||||
typedef struct { /* IGP band type */
|
typedef struct { /* IGP band type */
|
||||||
short x; /* longitude/latitude (deg) */
|
short x; /* longitude/latitude (deg) */
|
||||||
const short *y; /* latitudes/longitudes (deg) */
|
const short *y; /* latitudes/longitudes (deg) */
|
||||||
unsigned char bits; /* IGP mask start bit */
|
unsigned char bits; /* IGP mask start bit */
|
||||||
unsigned char bite; /* IGP mask end bit */
|
unsigned char bite; /* IGP mask end bit */
|
||||||
} sbsigpband_t;
|
} sbsigpband_t;
|
||||||
|
|
||||||
typedef struct { /* SBAS ionospheric corrections type */
|
typedef struct { /* SBAS ionospheric corrections type */
|
||||||
int iodi; /* IODI (issue of date ionos corr) */
|
int iodi; /* IODI (issue of date ionos corr) */
|
||||||
int nigp; /* number of igps */
|
int nigp; /* number of igps */
|
||||||
sbsigp_t igp[MAXNIGP]; /* ionospheric correction */
|
sbsigp_t igp[MAXNIGP]; /* ionospheric correction */
|
||||||
} sbsion_t;
|
} sbsion_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* idicators
|
* indicators
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct { /* SBAS ephemeris type */
|
typedef struct { /* SBAS ephemeris type */
|
||||||
int sat; /* satellite number */
|
int sat; /* satellite number */
|
||||||
//gtime_t t0; /* reference epoch time (GPST) */
|
//gtime_t t0; /* reference epoch time (GPST) */
|
||||||
int t0;
|
int t0;
|
||||||
//gtime_t tof; /* time of message frame (GPST) */
|
//gtime_t tof; /* time of message frame (GPST) */
|
||||||
double tof;
|
double tof;
|
||||||
int sva; /* SV accuracy (URA index) */
|
int sva; /* SV accuracy (URA index) */
|
||||||
int svh; /* SV health (0:ok) */
|
int svh; /* SV health (0:ok) */
|
||||||
double pos[3]; /* satellite position (m) (ecef) */
|
double pos[3]; /* satellite position (m) (ecef) */
|
||||||
double vel[3]; /* satellite velocity (m/s) (ecef) */
|
double vel[3]; /* satellite velocity (m/s) (ecef) */
|
||||||
double acc[3]; /* satellite acceleration (m/s^2) (ecef) */
|
double acc[3]; /* satellite acceleration (m/s^2) (ecef) */
|
||||||
double af0,af1; /* satellite clock-offset/drift (s,s/s) */
|
double af0,af1; /* satellite clock-offset/drift (s,s/s) */
|
||||||
} seph_t;
|
} seph_t;
|
||||||
|
|
||||||
typedef struct { /* navigation data type */
|
typedef struct { /* navigation data type */
|
||||||
//int n,nmax; /* number of broadcast ephemeris */
|
//int n,nmax; /* number of broadcast ephemeris */
|
||||||
//int ng,ngmax; /* number of glonass ephemeris */
|
//int ng,ngmax; /* number of glonass ephemeris */
|
||||||
//int ns,nsmax; /* number of sbas ephemeris */
|
//int ns,nsmax; /* number of sbas ephemeris */
|
||||||
//int ne,nemax; /* number of precise ephemeris */
|
//int ne,nemax; /* number of precise ephemeris */
|
||||||
//int nc,ncmax; /* number of precise clock */
|
//int nc,ncmax; /* number of precise clock */
|
||||||
//int na,namax; /* number of almanac data */
|
//int na,namax; /* number of almanac data */
|
||||||
//int nt,ntmax; /* number of tec grid data */
|
//int nt,ntmax; /* number of tec grid data */
|
||||||
//int nn,nnmax; /* number of stec grid data */
|
//int nn,nnmax; /* number of stec grid data */
|
||||||
//eph_t *eph; /* GPS/QZS/GAL ephemeris */
|
//eph_t *eph; /* GPS/QZS/GAL ephemeris */
|
||||||
//geph_t *geph; /* GLONASS ephemeris */
|
//geph_t *geph; /* GLONASS ephemeris */
|
||||||
seph_t seph[2*NSATSBS]; /* SBAS ephemeris */
|
seph_t seph[2*NSATSBS]; /* SBAS ephemeris */
|
||||||
// peph_t *peph; /* precise ephemeris */
|
// peph_t *peph; /* precise ephemeris */
|
||||||
// pclk_t *pclk; /* precise clock */
|
// pclk_t *pclk; /* precise clock */
|
||||||
// alm_t *alm; /* almanac data */
|
// alm_t *alm; /* almanac data */
|
||||||
// tec_t *tec; /* tec grid data */
|
// tec_t *tec; /* tec grid data */
|
||||||
// stec_t *stec; /* stec grid data */
|
// stec_t *stec; /* stec grid data */
|
||||||
// erp_t erp; /* earth rotation parameters */
|
// erp_t erp; /* earth rotation parameters */
|
||||||
|
|
||||||
//double utc_gps[4]; /* GPS delta-UTC parameters {A0,A1,T,W} */
|
//double utc_gps[4]; /* GPS delta-UTC parameters {A0,A1,T,W} */
|
||||||
//double utc_glo[4]; /* GLONASS UTC GPS time parameters */
|
//double utc_glo[4]; /* GLONASS UTC GPS time parameters */
|
||||||
//double utc_gal[4]; /* Galileo UTC GPS time parameters */
|
//double utc_gal[4]; /* Galileo UTC GPS time parameters */
|
||||||
//double utc_qzs[4]; /* QZS UTC GPS time parameters */
|
//double utc_qzs[4]; /* QZS UTC GPS time parameters */
|
||||||
//double utc_cmp[4]; /* BeiDou UTC parameters */
|
//double utc_cmp[4]; /* BeiDou UTC parameters */
|
||||||
//double utc_sbs[4]; /* SBAS UTC parameters */
|
//double utc_sbs[4]; /* SBAS UTC parameters */
|
||||||
//double ion_gps[8]; /* GPS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */
|
//double ion_gps[8]; /* GPS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */
|
||||||
//double ion_gal[4]; /* Galileo iono model parameters {ai0,ai1,ai2,0} */
|
//double ion_gal[4]; /* Galileo iono model parameters {ai0,ai1,ai2,0} */
|
||||||
//double ion_qzs[8]; /* QZSS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */
|
//double ion_qzs[8]; /* QZSS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */
|
||||||
//double ion_cmp[8]; /* BeiDou iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */
|
//double ion_cmp[8]; /* BeiDou iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */
|
||||||
//int leaps; /* leap seconds (s) */
|
//int leaps; /* leap seconds (s) */
|
||||||
//double lam[MAXSAT][NFREQ]; /* carrier wave lengths (m) */
|
//double lam[MAXSAT][NFREQ]; /* carrier wave lengths (m) */
|
||||||
//double cbias[MAXSAT][3]; /* code bias (0:p1-p2,1:p1-c1,2:p2-c2) (m) */
|
//double cbias[MAXSAT][3]; /* code bias (0:p1-p2,1:p1-c1,2:p2-c2) (m) */
|
||||||
//double wlbias[MAXSAT]; /* wide-lane bias (cycle) */
|
//double wlbias[MAXSAT]; /* wide-lane bias (cycle) */
|
||||||
//double glo_cpbias[4]; /* glonass code-phase bias {1C,1P,2C,2P} (m) */
|
//double glo_cpbias[4]; /* glonass code-phase bias {1C,1P,2C,2P} (m) */
|
||||||
//char glo_fcn[MAXPRNGLO+1]; /* glonass frequency channel number + 8 */
|
//char glo_fcn[MAXPRNGLO+1]; /* glonass frequency channel number + 8 */
|
||||||
// pcv_t pcvs[MAXSAT]; /* satellite antenna pcv */
|
// pcv_t pcvs[MAXSAT]; /* satellite antenna pcv */
|
||||||
sbssat_t sbssat; /* SBAS satellite corrections */
|
sbssat_t sbssat; /* SBAS satellite corrections */
|
||||||
sbsion_t sbsion[MAXBAND+1]; /* SBAS ionosphere corrections */
|
sbsion_t sbsion[MAXBAND+1]; /* SBAS ionosphere corrections */
|
||||||
// dgps_t dgps[MAXSAT]; /* DGPS corrections */
|
// dgps_t dgps[MAXSAT]; /* DGPS corrections */
|
||||||
// ssr_t ssr[MAXSAT]; /* SSR corrections */
|
// ssr_t ssr[MAXSAT]; /* SSR corrections */
|
||||||
// lexeph_t lexeph[MAXSAT]; /* LEX ephemeris */
|
// lexeph_t lexeph[MAXSAT]; /* LEX ephemeris */
|
||||||
// lexion_t lexion; /* LEX ionosphere correction */
|
// lexion_t lexion; /* LEX ionosphere correction */
|
||||||
} nav_t;
|
} nav_t;
|
||||||
|
|
||||||
//// common
|
//// common
|
||||||
|
|
||||||
static const double gpst0[]; /* gps time reference */
|
static const double gpst0[]; /* gps time reference */
|
||||||
|
|
||||||
/* debug trace functions -----------------------------------------------------*/
|
/* debug trace functions -----------------------------------------------------*/
|
||||||
|
|
||||||
FILE *fp_trace; /* file pointer of trace */
|
FILE *fp_trace; /* file pointer of trace */
|
||||||
int level_trace; /* level of trace */
|
int level_trace; /* level of trace */
|
||||||
unsigned int tick_trace; /* tick time at traceopen (ms) */
|
unsigned int tick_trace; /* tick time at traceopen (ms) */
|
||||||
|
|
||||||
void trace(int level, const char *format, ...);
|
void trace(int level, const char *format, ...);
|
||||||
|
|
||||||
/* satellite system+prn/slot number to satellite number ------------------------
|
/* satellite system+prn/slot number to satellite number ------------------------
|
||||||
* convert satellite system+prn/slot number to satellite number
|
* convert satellite system+prn/slot number to satellite number
|
||||||
* args : int sys I satellite system (SYS_GPS,SYS_GLO,...)
|
* args : int sys I satellite system (SYS_GPS,SYS_GLO,...)
|
||||||
* int prn I satellite prn/slot number
|
* int prn I satellite prn/slot number
|
||||||
* return : satellite number (0:error)
|
* return : satellite number (0:error)
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
int satno(int sys, int prn);
|
int satno(int sys, int prn);
|
||||||
/* extract unsigned/signed bits ------------------------------------------------
|
/* extract unsigned/signed bits ------------------------------------------------
|
||||||
* extract unsigned/signed bits from byte data
|
* extract unsigned/signed bits from byte data
|
||||||
* args : unsigned char *buff I byte data
|
* args : unsigned char *buff I byte data
|
||||||
* int pos I bit position from start of data (bits)
|
* int pos I bit position from start of data (bits)
|
||||||
* int len I bit length (bits) (len<=32)
|
* int len I bit length (bits) (len<=32)
|
||||||
* return : extracted unsigned/signed bits
|
* return : extracted unsigned/signed bits
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
unsigned int getbitu(const unsigned char *buff, int pos, int len);
|
unsigned int getbitu(const unsigned char *buff, int pos, int len);
|
||||||
int getbits(const unsigned char *buff, int pos, int len);
|
int getbits(const unsigned char *buff, int pos, int len);
|
||||||
|
|
||||||
/* convert calendar day/time to time -------------------------------------------
|
/* convert calendar day/time to time -------------------------------------------
|
||||||
* convert calendar day/time to gtime_t struct
|
* convert calendar day/time to gtime_t struct
|
||||||
* args : double *ep I day/time {year,month,day,hour,min,sec}
|
* args : double *ep I day/time {year,month,day,hour,min,sec}
|
||||||
* return : gtime_t struct
|
* return : gtime_t struct
|
||||||
* notes : proper in 1970-2037 or 1970-2099 (64bit time_t)
|
* notes : proper in 1970-2037 or 1970-2099 (64bit time_t)
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
gtime_t epoch2time(const double *ep);
|
gtime_t epoch2time(const double *ep);
|
||||||
/* time difference -------------------------------------------------------------
|
/* time difference -------------------------------------------------------------
|
||||||
* difference between gtime_t structs
|
* difference between gtime_t structs
|
||||||
* args : gtime_t t1,t2 I gtime_t structs
|
* args : gtime_t t1,t2 I gtime_t structs
|
||||||
* return : time difference (t1-t2) (s)
|
* return : time difference (t1-t2) (s)
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
double timediff(gtime_t t1, gtime_t t2);
|
double timediff(gtime_t t1, gtime_t t2);
|
||||||
/* gps time to time ------------------------------------------------------------
|
/* gps time to time ------------------------------------------------------------
|
||||||
* convert week and tow in gps time to gtime_t struct
|
* convert week and tow in gps time to gtime_t struct
|
||||||
* args : int week I week number in gps time
|
* args : int week I week number in gps time
|
||||||
* double sec I time of week in gps time (s)
|
* double sec I time of week in gps time (s)
|
||||||
* return : gtime_t struct
|
* return : gtime_t struct
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
gtime_t gpst2time(int week, double sec);
|
gtime_t gpst2time(int week, double sec);
|
||||||
|
|
||||||
|
|
||||||
////// sbas.c
|
////// sbas.c
|
||||||
|
|
||||||
/* sbas igp definition -------------------------------------------------------*/
|
/* sbas igp definition -------------------------------------------------------*/
|
||||||
static const short
|
static const short
|
||||||
x1[],
|
x1[],
|
||||||
x2[],
|
x2[],
|
||||||
x3[],
|
x3[],
|
||||||
x4[],
|
x4[],
|
||||||
x5[],
|
x5[],
|
||||||
x6[],
|
x6[],
|
||||||
x7[],
|
x7[],
|
||||||
x8[];
|
x8[];
|
||||||
|
|
||||||
static const sbsigpband_t igpband1[9][8];/* band 0-8 */
|
static const sbsigpband_t igpband1[9][8]; /* band 0-8 */
|
||||||
static const sbsigpband_t igpband2[2][5];/* band 9-10 */
|
static const sbsigpband_t igpband2[2][5]; /* band 9-10 */
|
||||||
|
|
||||||
/* decode type 1: prn masks --------------------------------------------------*/
|
/* decode type 1: prn masks --------------------------------------------------*/
|
||||||
int decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat);
|
int decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat);
|
||||||
/* decode type 2-5,0: fast corrections ---------------------------------------*/
|
/* decode type 2-5,0: fast corrections ---------------------------------------*/
|
||||||
int decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat);
|
int decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat);
|
||||||
/* decode type 6: integrity info ---------------------------------------------*/
|
/* decode type 6: integrity info ---------------------------------------------*/
|
||||||
int decode_sbstype6(const sbsmsg_t *msg, sbssat_t *sbssat);
|
int decode_sbstype6(const sbsmsg_t *msg, sbssat_t *sbssat);
|
||||||
/* decode type 7: fast correction degradation factor -------------------------*/
|
/* decode type 7: fast correction degradation factor -------------------------*/
|
||||||
int decode_sbstype7(const sbsmsg_t *msg, sbssat_t *sbssat);
|
int decode_sbstype7(const sbsmsg_t *msg, sbssat_t *sbssat);
|
||||||
/* decode type 9: geo navigation message -------------------------------------*/
|
/* decode type 9: geo navigation message -------------------------------------*/
|
||||||
int decode_sbstype9(const sbsmsg_t *msg, nav_t *nav);
|
int decode_sbstype9(const sbsmsg_t *msg, nav_t *nav);
|
||||||
/* decode type 18: ionospheric grid point masks ------------------------------*/
|
/* decode type 18: ionospheric grid point masks ------------------------------*/
|
||||||
int decode_sbstype18(const sbsmsg_t *msg, sbsion_t *sbsion);
|
int decode_sbstype18(const sbsmsg_t *msg, sbsion_t *sbsion);
|
||||||
/* decode half long term correction (vel code=0) -----------------------------*/
|
/* decode half long term correction (vel code=0) -----------------------------*/
|
||||||
int decode_longcorr0(const sbsmsg_t *msg, int p, sbssat_t *sbssat);
|
int decode_longcorr0(const sbsmsg_t *msg, int p, sbssat_t *sbssat);
|
||||||
/* decode half long term correction (vel code=1) -----------------------------*/
|
/* decode half long term correction (vel code=1) -----------------------------*/
|
||||||
int decode_longcorr1(const sbsmsg_t *msg, int p, sbssat_t *sbssat);
|
int decode_longcorr1(const sbsmsg_t *msg, int p, sbssat_t *sbssat);
|
||||||
/* decode half long term correction ------------------------------------------*/
|
/* decode half long term correction ------------------------------------------*/
|
||||||
int decode_longcorrh(const sbsmsg_t *msg, int p, sbssat_t *sbssat);
|
int decode_longcorrh(const sbsmsg_t *msg, int p, sbssat_t *sbssat);
|
||||||
/* decode type 24: mixed fast/long term correction ---------------------------*/
|
/* decode type 24: mixed fast/long term correction ---------------------------*/
|
||||||
int decode_sbstype24(const sbsmsg_t *msg, sbssat_t *sbssat);
|
int decode_sbstype24(const sbsmsg_t *msg, sbssat_t *sbssat);
|
||||||
/* decode type 25: long term satellite error correction ----------------------*/
|
/* decode type 25: long term satellite error correction ----------------------*/
|
||||||
int decode_sbstype25(const sbsmsg_t *msg, sbssat_t *sbssat);
|
int decode_sbstype25(const sbsmsg_t *msg, sbssat_t *sbssat);
|
||||||
/* decode type 26: ionospheric deley corrections -----------------------------*/
|
/* decode type 26: ionospheric deley corrections -----------------------------*/
|
||||||
int decode_sbstype26(const sbsmsg_t *msg, sbsion_t *sbsion);
|
int decode_sbstype26(const sbsmsg_t *msg, sbsion_t *sbsion);
|
||||||
/* update sbas corrections -----------------------------------------------------
|
/* update sbas corrections -----------------------------------------------------
|
||||||
* update sbas correction parameters in navigation data with a sbas message
|
* update sbas correction parameters in navigation data with a sbas message
|
||||||
* args : sbsmg_t *msg I sbas message
|
* args : sbsmg_t *msg I sbas message
|
||||||
* nav_t *nav IO navigation data
|
* nav_t *nav IO navigation data
|
||||||
* return : message type (-1: error or not supported type)
|
* return : message type (-1: error or not supported type)
|
||||||
* notes : nav->seph must point to seph[NSATSBS*2] (array of seph_t)
|
* notes : nav->seph must point to seph[NSATSBS*2] (array of seph_t)
|
||||||
* seph[prn-MINPRNSBS+1] : sat prn current epehmeris
|
* seph[prn-MINPRNSBS+1] : sat prn current epehmeris
|
||||||
* seph[prn-MINPRNSBS+1+MAXPRNSBS]: sat prn previous epehmeris
|
* seph[prn-MINPRNSBS+1+MAXPRNSBS]: sat prn previous epehmeris
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
int sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav);
|
int sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav);
|
||||||
|
|
||||||
void prn_mask_changed();
|
void prn_mask_changed();
|
||||||
bool is_rtklib_sat_correction_valid(int sat);
|
bool is_rtklib_sat_correction_valid(int sat);
|
||||||
void igp_mask_changed(int band);
|
void igp_mask_changed(int band);
|
||||||
|
|
||||||
// RTKLIB SBAS telemetry data representation
|
|
||||||
nav_t d_nav;
|
|
||||||
|
|
||||||
|
// RTKLIB SBAS telemetry data representation
|
||||||
|
nav_t d_nav;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -61,7 +61,7 @@ public:
|
|||||||
bool to_gps_time(double time_stamp_sec, int &gps_week, double &gps_sec)
|
bool to_gps_time(double time_stamp_sec, int &gps_week, double &gps_sec)
|
||||||
{
|
{
|
||||||
int delta_weeks = int(trunc(time_stamp_sec + d_delta_sec))/604800;
|
int delta_weeks = int(trunc(time_stamp_sec + d_delta_sec))/604800;
|
||||||
gps_sec = time_stamp_sec+d_delta_sec-delta_weeks*604800;
|
gps_sec = time_stamp_sec + d_delta_sec - delta_weeks*604800;
|
||||||
gps_week = i_gps_week + delta_weeks;
|
gps_week = i_gps_week + delta_weeks;
|
||||||
VLOG(FLOW) << "<<R>> to gps time: time_stamp_sec=" << time_stamp_sec << " gps_week=" << gps_week << " gps_sec=" << gps_sec;
|
VLOG(FLOW) << "<<R>> to gps time: time_stamp_sec=" << time_stamp_sec << " gps_week=" << gps_week << " gps_sec=" << gps_sec;
|
||||||
return b_valid;
|
return b_valid;
|
||||||
@ -86,18 +86,16 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*!
|
||||||
* Sbas_Time relates the relative sample stamp time scale with the absolute GPS time scale.
|
* \brief Sbas_Time relates the relative sample stamp time scale with the absolute GPS time scale.
|
||||||
* There are three different states for a Sbas_Time object:
|
* There are three different states for a Sbas_Time object:
|
||||||
* - only relative time (sample stamp) is known
|
* - only relative time (sample stamp) is known
|
||||||
* - only absolute time (gps time) is known
|
* - only absolute time (gps time) is known
|
||||||
* - absolute and relative time and their relation is known
|
* - absolute and relative time and their relation is known
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Sbas_Time
|
class Sbas_Time
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Sbas_Time_State {RELATIVE, /*ABSOLUTE,*/ RELATED, UNDEFINED};
|
enum Sbas_Time_State {RELATIVE, /*ABSOLUTE,*/ RELATED, UNDEFINED};
|
||||||
|
|
||||||
Sbas_Time()
|
Sbas_Time()
|
||||||
@ -177,10 +175,10 @@ public:
|
|||||||
return (/*e_state == ABSOLUTE ||*/ e_state == RELATED);
|
return (/*e_state == ABSOLUTE ||*/ e_state == RELATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_only_relativ() {return e_state == RELATIVE;}
|
bool is_only_relativ() { return e_state == RELATIVE; }
|
||||||
//bool is_only_absolute() {return e_state == ABSOLUTE;}
|
//bool is_only_absolute() {return e_state == ABSOLUTE;}
|
||||||
bool is_related() {return e_state == RELATED;}
|
bool is_related() { return e_state == RELATED; }
|
||||||
Sbas_Time_State get_state() {return e_state;}
|
Sbas_Time_State get_state() { return e_state; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Sbas_Time_State e_state;
|
Sbas_Time_State e_state;
|
||||||
@ -190,4 +188,4 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* SBAS_TIME_H_ */
|
#endif /* GNSS_SDR_SBAS_TIME_H_ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user