- Timestamp:
- Dec 10, 2015, 3:35:44 PM (9 years ago)
- Location:
- trunk/BNC/src/RTCM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/BNC/src/RTCM/RTCM2.cpp
r6788 r7629 2 2 // 3 3 // RTCM2.cpp 4 // 5 // Purpose: 4 // 5 // Purpose: 6 6 // 7 7 // Module for extraction of RTCM2 messages … … 11 11 // RTCM 10402.3 Recommended Standards for Differential GNSS (Global 12 12 // Navigation Satellite Systems) Service; RTCM Paper 136-2001/SC104-STD, 13 // Version 2.3, 20 Aug. 2001; Radio Technical Commission For Maritime 13 // Version 2.3, 20 Aug. 2001; Radio Technical Commission For Maritime 14 14 // Services, Alexandria, Virgina (2001). 15 15 // ICD-GPS-200; Navstar GPS Space Segment / Navigation User Interfaces; … … 22 22 // last accessed 17 Sep. 2006 23 23 // 24 // Notes: 24 // Notes: 25 25 // 26 26 // - The host computer is assumed to use little endian (Intel) byte order … … 36 36 // 2006/10/14 LMV Exception handling 37 37 // 2006/10/17 OMO Removed obsolete check of multiple message indicator 38 // 2006/10/17 OMO Fixed parity handling 38 // 2006/10/17 OMO Fixed parity handling 39 39 // 2006/10/18 OMO Improved screening of bad data in RTCM2_Obs::extract 40 40 // 2006/11/25 OMO Revised check for presence of GLONASS data 41 41 // 2007/05/25 GW Round time tag to 100 ms 42 // 2007/12/11 AHA Changed handling of C/A- and P-Code on L1 43 // 2007/12/13 AHA Changed epoch comparison in packet extraction 42 // 2007/12/11 AHA Changed handling of C/A- and P-Code on L1 43 // 2007/12/13 AHA Changed epoch comparison in packet extraction 44 44 // 2008/03/01 OMO Compilation flag for epoch rounding 45 45 // 2008/03/04 AHA Fixed problems with PRN 32 46 46 // 2008/03/05 AHA Implemeted fix for Trimble 4000SSI receivers 47 // 2008/03/07 AHA Major revision of input buffer handling 47 // 2008/03/07 AHA Major revision of input buffer handling 48 48 // 2008/03/07 AHA Removed unnecessary failure flag 49 49 // 2008/03/10 AHA Corrected extraction of antenna serial number … … 76 76 // Note: A need to round the measurement epoch to integer tenths of a second was 77 77 // noted by BKG in the processing of RTCM2 data from various receivers in NTRIP 78 // real-time networks. It is unclear at present, whether this is due to an 78 // real-time networks. It is unclear at present, whether this is due to an 79 79 // improper implementation of the RTCM2 standard in the respective receivers 80 // or an unclear formulation of the standard. 80 // or an unclear formulation of the standard. 81 81 82 82 #define ROUND_EPOCH 1 … … 84 84 // Fix for data streams originating from TRIMBLE_4000SSI receivers. 85 85 // GPS PRN32 is erroneously flagged as GLONASS satellite in the C/A 86 // pseudorange messages. We therefore use a majority voting to 86 // pseudorange messages. We therefore use a majority voting to 87 87 // determine the true constellation for this message. 88 88 // This fix is only required for Trimble4000SSI receivers but can also … … 101 101 102 102 const double lambda_L1 = c_light/f_L1; // L1 wavelength [m] (0.1903m) 103 const double lambda_L2 = c_light/f_L2; // L2 wavelength [m] 103 const double lambda_L2 = c_light/f_L2; // L2 wavelength [m] 104 104 105 105 // … … 107 107 // 108 108 109 const int bit_L1rngGPS = 0; 110 const int bit_L2rngGPS = 1; 111 const int bit_L1cphGPS = 2; 112 const int bit_L2cphGPS = 3; 113 const int bit_L1rngGLO = 4; 114 const int bit_L2rngGLO = 5; 115 const int bit_L1cphGLO = 6; 116 const int bit_L2cphGLO = 7; 109 const int bit_L1rngGPS = 0; 110 const int bit_L2rngGPS = 1; 111 const int bit_L1cphGPS = 2; 112 const int bit_L2cphGPS = 3; 113 const int bit_L1rngGLO = 4; 114 const int bit_L2rngGLO = 5; 115 const int bit_L1cphGLO = 6; 116 const int bit_L2cphGLO = 7; 117 117 118 118 … … 122 122 123 123 namespace rtcm2 { 124 124 125 125 //------------------------------------------------------------------------------ 126 126 // … … 128 128 // 129 129 // Purpose: 130 // 130 // 131 131 // Handling of RTCM2 30bit words 132 132 // … … 148 148 bool ThirtyBitWord::validParity() const { 149 149 150 // Parity stuff 150 // Parity stuff 151 151 152 152 static const unsigned int PARITY_25 = 0xBB1F3480; … … 173 173 174 174 unsigned int t, w, p; 175 176 // The sign of the data is determined by the D30* parity bit 177 // of the previous data word. If D30* is set, invert the data 175 176 // The sign of the data is determined by the D30* parity bit 177 // of the previous data word. If D30* is set, invert the data 178 178 // bits D01..D24 to obtain the d01..d24 (but leave all other 179 179 // bits untouched). 180 180 181 181 w = W; 182 182 if ( w & 0x40000000 ) w ^= 0x3FFFFFC0; … … 188 188 p = ( byteParity[t &0xff] ^ byteParity[(t>> 8)&0xff] ^ 189 189 byteParity[(t>>16)&0xff] ^ byteParity[(t>>24) ] ); 190 190 191 191 t = w & PARITY_26; 192 p = (p<<1) | 192 p = (p<<1) | 193 193 ( byteParity[t &0xff] ^ byteParity[(t>> 8)&0xff] ^ 194 194 byteParity[(t>>16)&0xff] ^ byteParity[(t>>24) ] ); 195 195 196 196 t = w & PARITY_27; 197 p = (p<<1) | 197 p = (p<<1) | 198 198 ( byteParity[t &0xff] ^ byteParity[(t>> 8)&0xff] ^ 199 199 byteParity[(t>>16)&0xff] ^ byteParity[(t>>24) ] ); 200 200 201 201 t = w & PARITY_28; 202 p = (p<<1) | 202 p = (p<<1) | 203 203 ( byteParity[t &0xff] ^ byteParity[(t>> 8)&0xff] ^ 204 204 byteParity[(t>>16)&0xff] ^ byteParity[(t>>24) ] ); 205 205 206 206 t = w & PARITY_29; 207 p = (p<<1) | 207 p = (p<<1) | 208 208 ( byteParity[t &0xff] ^ byteParity[(t>> 8)&0xff] ^ 209 209 byteParity[(t>>16)&0xff] ^ byteParity[(t>>24) ] ); 210 210 211 211 t = w & PARITY_30; 212 p = (p<<1) | 212 p = (p<<1) | 213 213 ( byteParity[t &0xff] ^ byteParity[(t>> 8)&0xff] ^ 214 214 byteParity[(t>>16)&0xff] ^ byteParity[(t>>24) ] ); … … 224 224 225 225 const unsigned char Preamble = 0x66; 226 226 227 227 unsigned char b = (value()>>22) & 0xFF; 228 228 229 229 return ( b==Preamble ); 230 230 … … 244 244 245 245 unsigned int w = W; 246 246 247 247 if (validParity()) { 248 // Return data and current parity bits. Invert data bits if D30* 248 // Return data and current parity bits. Invert data bits if D30* 249 249 // is set and discard old parity bits. 250 250 if ( w & 0x40000000 ) w ^= 0x3FFFFFC0; … … 255 255 return 0; 256 256 }; 257 257 258 258 }; 259 259 … … 262 262 263 263 void ThirtyBitWord::append(unsigned char b) { 264 264 265 265 // Look up table for swap (left-right) of 6 data bits 266 static const unsigned char 267 swap[] = { 268 0,32,16,48, 8,40,24,56, 4,36,20,52,12,44,28,60, 269 2,34,18,50,10,42,26,58, 6,38,22,54,14,46,30,62, 270 1,33,17,49, 9,41,25,57, 5,37,21,53,13,45,29,61, 271 3,35,19,51,11,43,27,59, 7,39,23,55,15,47,31,63 266 static const unsigned char 267 swap[] = { 268 0,32,16,48, 8,40,24,56, 4,36,20,52,12,44,28,60, 269 2,34,18,50,10,42,26,58, 6,38,22,54,14,46,30,62, 270 1,33,17,49, 9,41,25,57, 5,37,21,53,13,45,29,61, 271 3,35,19,51,11,43,27,59, 7,39,23,55,15,47,31,63 272 272 }; 273 273 274 274 // Bits 7 and 6 (of 0..7) must be "01" for valid data bytes 275 275 if ( (b & 0x40) != 0x40 ) { 276 276 // We simply skip the invalid input byte and leave the word unchanged 277 #if (DEBUG>0) 277 #if (DEBUG>0) 278 278 cerr << "Error in append()" << bitset<32>(all()) << endl; 279 279 #endif 280 280 return; 281 281 }; 282 282 283 283 // Swap bits 0..5 to restore proper bit order for 30bit words 284 284 b = swap[ b & 0x3f]; 285 285 286 286 // Fill word 287 W = ( (W <<6) | (b & 0x3f) ) ; 288 287 W = ( (W <<6) | (b & 0x3f) ) ; 288 289 289 }; 290 290 … … 295 295 296 296 // Check if string is long enough 297 297 298 298 if (buf.size()<5) { 299 299 // Ignore; users should avoid this case prior to calling get() 300 301 #if ( DEBUG > 0 ) 300 301 #if ( DEBUG > 0 ) 302 302 cerr << "Error in get(): packet too short (" << buf.size() <<")" << endl; 303 303 #endif 304 304 305 305 return; 306 306 }; 307 307 308 308 // Process 5 bytes 309 309 310 310 for (int i=0; i<5; i++) append(buf[i]); 311 311 312 #if (DEBUG>0) 312 #if (DEBUG>0) 313 313 if (!validParity()) { 314 cerr << "Parity error in get()" 314 cerr << "Parity error in get()" 315 315 << bitset<32>(all()) << endl; 316 316 }; … … 326 326 327 327 for (int i=0; i<5; i++) { 328 inp >> b; 328 inp >> b; 329 329 if (inp.fail()) { clear(); return; }; 330 330 append(b); 331 331 }; 332 332 333 #if (DEBUG>0) 333 #if (DEBUG>0) 334 334 if (!validParity()) { 335 cerr << "Parity error in get()" 335 cerr << "Parity error in get()" 336 336 << bitset<32>(all()) << endl; 337 337 }; … … 346 346 const unsigned int wordLen = 5; // Number of bytes representing a 30-bit word 347 347 const unsigned int spare = 1; // Number of spare words for resync of parity 348 // (same value as inRTCM2packet::getPacket()) 348 // (same value as inRTCM2packet::getPacket()) 349 349 unsigned int i; 350 350 351 351 i=0; 352 // append spare word (to get correct parity) and first consecutive word 352 // append spare word (to get correct parity) and first consecutive word 353 353 while (i<(spare+1)*wordLen) { 354 354 // Process byte … … 357 357 i++; 358 358 }; 359 359 360 360 // start searching for preamble in first word after spare word 361 361 while (!isHeader() && i<buf.size() ) { … … 370 370 if (i>=(1+spare)*wordLen) buf.erase(0,i-(1+spare)*wordLen); 371 371 372 #if (DEBUG>0) 372 #if (DEBUG>0) 373 373 if (!validParity()) { 374 cerr << "Parity error in getHeader()" 374 cerr << "Parity error in getHeader()" 375 375 << bitset<32>(all()) << endl; 376 376 }; 377 377 #endif 378 378 379 379 }; 380 380 … … 388 388 i=0; 389 389 while ( !isHeader() || i<5 ) { 390 inp >> b; 390 inp >> b; 391 391 if (inp.fail()) { clear(); return; }; 392 392 append(b); i++; 393 393 }; 394 394 395 #if (DEBUG>0) 395 #if (DEBUG>0) 396 396 if (!validParity()) { 397 cerr << "Parity error in getHeader()" 397 cerr << "Parity error in getHeader()" 398 398 << bitset<32>(all()) << endl; 399 399 }; … … 422 422 423 423 void RTCM2packet::clear() { 424 424 425 425 W.clear(); 426 426 427 427 H1=0; 428 428 H2=0; 429 429 430 430 DW.resize(0,0); 431 431 432 432 }; 433 433 … … 435 435 436 436 bool RTCM2packet::valid() const { 437 437 438 438 // The methods for creating a packet (get,">>") ensure 439 // that a packet has a consistent number of data words 440 // and a valid parity in all header and data words. 439 // that a packet has a consistent number of data words 440 // and a valid parity in all header and data words. 441 441 // Therefore a packet is either empty or valid. 442 442 443 443 return (H1!=0); 444 444 445 445 }; 446 446 … … 456 456 // (same value as used in ThirtyBitWord::getHeader) 457 457 unsigned int n; 458 458 459 459 // Does the package content at least spare bytes and first header byte? 460 if (buf.size()<(spare+1)*wordLen) { 461 clear(); 460 if (buf.size()<(spare+1)*wordLen) { 461 clear(); 462 462 return; 463 463 }; 464 465 // Try to read a full packet. Processed bytes are removed from the input 466 // buffer except for the latest spare*wordLen bytes to restore the parity 464 465 // Try to read a full packet. Processed bytes are removed from the input 466 // buffer except for the latest spare*wordLen bytes to restore the parity 467 467 // bytes upon subseqeunt calls of getPacket(). 468 468 469 469 // Locate and read the first header word 470 470 W.getHeader(buf); 471 if (!W.isHeader()) { 471 if (!W.isHeader()) { 472 472 // No header found; try again next time. buf retains only the spare 473 473 // words. The packet contents is cleared to indicate an unsuccessful 474 474 // termination of getPacket(). 475 475 clear(); 476 476 477 477 #if ( DEBUG > 0 ) 478 478 cerr << "Error in getPacket(): W.isHeader() = false for H1" << endl; 479 479 #endif 480 481 return; 480 481 return; 482 482 }; 483 483 H1 = W.value(); 484 484 485 // Do we have enough bytes to read the next word? If not, the packet 485 // Do we have enough bytes to read the next word? If not, the packet 486 486 // contents is cleared to indicate an unsuccessful termination. The 487 487 // previously read spare and header bytes are retained in the buffer 488 488 // for use in the next call of getPacket(). 489 if (buf.size()<(spare+2)*wordLen) { 490 clear(); 491 492 #if ( DEBUG > 0 ) 489 if (buf.size()<(spare+2)*wordLen) { 490 clear(); 491 492 #if ( DEBUG > 0 ) 493 493 cerr << "Error in getPacket(): buffer too short for complete H2" << endl; 494 494 #endif 495 495 496 496 return; 497 497 }; 498 498 499 499 // Read the second header word 500 W.get(buf.substr((spare+1)*wordLen,buf.size()-(spare+1)*wordLen)); 500 W.get(buf.substr((spare+1)*wordLen,buf.size()-(spare+1)*wordLen)); 501 501 H2 = W.value(); 502 if (!W.validParity()) { 502 if (!W.validParity()) { 503 503 // Invalid H2 word; delete first buffer byte and try to resynch next time. 504 504 // The packet contents is cleared to indicate an unsuccessful termination. 505 clear(); 506 buf.erase(0,1); 507 508 #if ( DEBUG > 0 ) 505 clear(); 506 buf.erase(0,1); 507 508 #if ( DEBUG > 0 ) 509 509 cerr << "Error in getPacket(): W.validParity() = false for H2" << endl; 510 510 #endif 511 512 return; 511 512 return; 513 513 }; 514 514 515 515 n = nDataWords(); 516 517 // Do we have enough bytes to read the next word? If not, the packet 516 517 // Do we have enough bytes to read the next word? If not, the packet 518 518 // contents is cleared to indicate an unsuccessful termination. The 519 519 // previously read spare and header bytes are retained in the buffer 520 520 // for use in the next call of getPacket(). 521 if (buf.size()<(spare+2+n)*wordLen) { 522 clear(); 523 524 #if ( DEBUG > 0 ) 521 if (buf.size()<(spare+2+n)*wordLen) { 522 clear(); 523 524 #if ( DEBUG > 0 ) 525 525 cerr << "Error in getPacket(): buffer too short for complete " << n 526 526 << " DWs" << endl; 527 527 #endif 528 529 return; 530 }; 531 528 529 return; 530 }; 531 532 532 DW.resize(n); 533 533 for (unsigned int i=0; i<n; i++) { 534 W.get(buf.substr((spare+2+i)*wordLen,buf.size()-(spare+2+i)*wordLen)); 534 W.get(buf.substr((spare+2+i)*wordLen,buf.size()-(spare+2+i)*wordLen)); 535 535 DW[i] = W.value(); 536 if (!W.validParity()) { 536 if (!W.validParity()) { 537 537 // Invalid data word; delete first byte and try to resynch next time. 538 538 // The packet contents is cleared to indicate an unsuccessful termination. 539 clear(); 540 buf.erase(0,1); 541 542 #if ( DEBUG > 0 ) 539 clear(); 540 buf.erase(0,1); 541 542 #if ( DEBUG > 0 ) 543 543 cerr << "Error in getPacket(): W.validParity() = false for DW" 544 544 << i << endl; 545 545 #endif 546 547 return; 546 547 return; 548 548 }; 549 549 }; 550 550 551 // Successful packet extraction; delete total number of message bytes 552 // from buffer. 551 // Successful packet extraction; delete total number of message bytes 552 // from buffer. 553 553 // Note: a total of "spare" words remain in the buffer to enable a 554 554 // parity resynchronization when searching the next header. 555 555 556 556 buf.erase(0,(n+2)*wordLen); 557 557 558 558 return; 559 559 560 560 }; 561 561 … … 568 568 569 569 int n; 570 571 W.getHeader(inp); 572 H1 = W.value(); 570 571 W.getHeader(inp); 572 H1 = W.value(); 573 573 if (inp.fail() || !W.isHeader()) { clear(); return; } 574 575 W.get(inp); 576 H2 = W.value(); 574 575 W.get(inp); 576 H2 = W.value(); 577 577 if (inp.fail() || !W.validParity()) { clear(); return; } 578 578 … … 580 580 DW.resize(n); 581 581 for (int i=0; i<n; i++) { 582 W.get(inp); 583 DW[i] = W.value(); 582 W.get(inp); 583 DW[i] = W.value(); 584 584 if (inp.fail() || !W.validParity()) { clear(); return; } 585 585 }; 586 586 587 587 return; 588 588 589 589 }; 590 590 … … 592 592 // Input operator 593 593 // 594 // Reads an RTCM2 packet from the input stream. 594 // Reads an RTCM2 packet from the input stream. 595 595 // 596 596 … … 598 598 599 599 p.getPacket(is); 600 600 601 601 return is; 602 602 603 603 }; 604 604 … … 653 653 // 654 654 655 unsigned int RTCM2packet::getUnsignedBits ( unsigned int start, 655 unsigned int RTCM2packet::getUnsignedBits ( unsigned int start, 656 656 unsigned int n ) const { 657 657 658 658 unsigned int iFirst = start/24; // Index of first data word 659 659 unsigned int iLast = (start+n-1)/24; // Index of last data word 660 660 unsigned int bitField = 0; 661 661 unsigned int tmp; 662 662 663 663 // Checks 664 664 665 665 if (n>32) { 666 666 throw("Error: can't handle >32 bits in RTCM2packet::getUnsignedBits"); 667 667 }; 668 668 669 669 if ( 24*DW.size() < start+n-1 ) { 670 670 #if (DEBUG>0) … … 683 683 684 684 // Handle initial data word 685 // Get all data bits. Strip parity and unwanted leading bits. 686 // Store result in 24 lsb bits of tmp. 687 688 tmp = (DW[iFirst]>>6) & 0xFFFFFF; 685 // Get all data bits. Strip parity and unwanted leading bits. 686 // Store result in 24 lsb bits of tmp. 687 688 tmp = (DW[iFirst]>>6) & 0xFFFFFF; 689 689 tmp = ( ( tmp << start%24) & 0xFFFFFF ) >> start%24 ; 690 690 691 691 // Handle central data word 692 693 if ( iFirst<iLast ) { 692 693 if ( iFirst<iLast ) { 694 694 bitField = tmp; 695 695 for (unsigned int iWord=iFirst+1; iWord<iLast; iWord++) { 696 tmp = (DW[iWord]>>6) & 0xFFFFFF; 696 tmp = (DW[iWord]>>6) & 0xFFFFFF; 697 697 bitField = (bitField << 24) | tmp; 698 698 }; 699 tmp = (DW[iLast]>>6) & 0xFFFFFF; 699 tmp = (DW[iLast]>>6) & 0xFFFFFF; 700 700 }; 701 701 702 702 // Handle last data word 703 703 704 704 tmp = tmp >> (23-(start+n-1)%24); 705 705 bitField = (bitField << ((start+n-1)%24+1)) | tmp; 706 706 707 707 // Done 708 708 709 709 return bitField; 710 710 711 711 }; 712 712 … … 717 717 // 718 718 719 int RTCM2packet::getBits ( unsigned int start, 719 int RTCM2packet::getBits ( unsigned int start, 720 720 unsigned int n ) const { 721 721 722 722 723 723 // Checks 724 724 725 725 if (n>32) { 726 726 throw("Error: can't handle >32 bits in RTCM2packet::getBits"); 727 727 }; 728 728 729 729 if ( 24*DW.size() < start+n-1 ) { 730 730 #if (DEBUG>0) … … 743 743 744 744 return ((int)(getUnsignedBits(start,n)<<(32-n))>>(32-n)); 745 745 746 746 }; 747 747 … … 757 757 //------------------------------------------------------------------------------ 758 758 759 // Constructor760 RTCM2_03::RTCM2_03(){761 validMsg = false;762 x = 0.0;763 y = 0.0;764 z=0.0;765 };766 759 767 760 void RTCM2_03::extract(const RTCM2packet& P) { 768 761 769 762 // Check validity, packet type and number of data words 770 771 validMsg = (P.valid()); 763 764 validMsg = (P.valid()); 772 765 if (!validMsg) return; 773 766 774 validMsg = (P.ID()==03); 767 validMsg = (P.ID()==03); 775 768 if (!validMsg) return; 776 777 validMsg = (P.nDataWords()==4); 769 770 validMsg = (P.nDataWords()==4); 778 771 if (!validMsg) return; 779 772 780 773 // Antenna reference point coordinates 781 774 782 775 x = P.getBits( 0,32)*0.01; // X [m] 783 776 y = P.getBits(32,32)*0.01; // Y [m] … … 799 792 800 793 unsigned int nad, nas; 801 794 802 795 const unsigned int nF1 = 8; // bits in first field (R,AF,SF,NAD) 803 796 const unsigned int nF2 =16; // bits in second field (SETUP ID,R,NAS) 804 797 const unsigned int nBits=24; // data bits in 30bit word 805 798 806 799 // Check validity, packet type and number of data words 807 808 validMsg = (P.valid()); 800 801 validMsg = (P.valid()); 809 802 if (!validMsg) return; 810 803 811 validMsg = (P.ID()==23); 804 validMsg = (P.ID()==23); 812 805 if (!validMsg) return; 813 806 814 807 // Check number of data words (can nad be read in?) 815 816 validMsg = (P.nDataWords()>=1); 808 809 validMsg = (P.nDataWords()>=1); 817 810 if (!validMsg){ 818 811 cerr << "RTCM2_23::extract: P.nDataWords()>=1" << endl; … … 820 813 } 821 814 822 // Antenna descriptor 815 // Antenna descriptor 823 816 antType = ""; 824 817 nad = P.getUnsignedBits(3,5); 825 826 // Check number of data words (can antenna description be read in?) 827 validMsg = ( P.nDataWords() >= 818 819 // Check number of data words (can antenna description be read in?) 820 validMsg = ( P.nDataWords() >= 828 821 (unsigned int)ceil((nF1+nad*8)/(double)nBits) ); 829 822 830 823 if (!validMsg) return; 831 832 for (unsigned int i=0;i<nad;i++) 824 825 for (unsigned int i=0;i<nad;i++) 833 826 antType += (char)P.getUnsignedBits(nF1+i*8,8); 834 827 … … 837 830 838 831 // Check number of data words (can nas be read in?) 839 832 840 833 validMsg = ( P.nDataWords() >= 841 834 (unsigned int)ceil((nF1+nad*8+nF2)/(double)nBits) ); 842 835 if (!validMsg) return; 843 836 844 837 nas = P.getUnsignedBits(19+8*nad,5); 845 838 846 839 // Check number of data words (can antenna serial number be read in?) 847 840 848 841 validMsg = ( P.nDataWords() >= 849 842 (unsigned int)ceil((nF1+nad*8+nF2+nas*8)/(double)nBits) ); … … 851 844 852 845 antSN = ""; 853 for (unsigned int i=0;i<nas;i++) 846 for (unsigned int i=0;i<nas;i++) 854 847 antSN += (char)P.getUnsignedBits(nF1+8*nad+nF2+i*8,8); 855 848 }; … … 864 857 // Purpose: 865 858 // 866 // A class for handling RTCM 2 Reference Station Antenna 859 // A class for handling RTCM 2 Reference Station Antenna 867 860 // Reference Point Parameter messages 868 861 // … … 874 867 875 868 // Check validity, packet type and number of data words 876 877 validMsg = (P.valid()); 869 870 validMsg = (P.valid()); 878 871 if (!validMsg) return; 879 872 880 validMsg = (P.ID()==24); 873 validMsg = (P.ID()==24); 881 874 if (!validMsg) return; 882 883 validMsg = (P.nDataWords()==6); 875 876 validMsg = (P.nDataWords()==6); 884 877 if (!validMsg) return; 885 878 886 879 // System indicator 887 880 888 881 isGPS = (P.getUnsignedBits(118,1)==0); 889 882 isGLONASS = (P.getUnsignedBits(118,1)==1); 890 883 891 884 // Antenna reference point coordinates 892 885 … … 902 895 903 896 // Antenna Height 904 897 905 898 if (P.getUnsignedBits(119,1)==1) { 906 899 h= P.getUnsignedBits(120,18)*0.0001; … … 917 910 // Purpose: 918 911 // 919 // A class for handling blocks of RTCM2 18 & 19 packets that need to be 912 // A class for handling blocks of RTCM2 18 & 19 packets that need to be 920 913 // combined to get a complete set of measurements 921 914 // … … 923 916 // 924 917 // The class collects L1/L2 code and phase measurements for GPS and GLONASS. 925 // Since the Multiple Message Indicator is inconsistently handled by various 918 // Since the Multiple Message Indicator is inconsistently handled by various 926 919 // receivers we simply require code and phase on L1 and L2 for a complete 927 // set ob observations at a given epoch. GLONASS observations are optional, 928 // but all four types (code+phase,L1+L2) must be provided, if at least one 929 // is given. Also, the GLONASS message must follow the corresponding GPS 920 // set ob observations at a given epoch. GLONASS observations are optional, 921 // but all four types (code+phase,L1+L2) must be provided, if at least one 922 // is given. Also, the GLONASS message must follow the corresponding GPS 930 923 // message. 931 924 // … … 940 933 }; 941 934 942 // Reset entire block 935 // Reset entire block 943 936 944 937 void RTCM2_Obs::clear() { 945 938 946 939 GPSonly = true; 947 940 948 941 secs=0.0; // Seconds of hour (GPS time) 949 942 nSat=0; // Number of space vehicles … … 956 949 slip_L1.resize(0); // Slip counter 957 950 slip_L2.resize(0); // Slip counter 958 951 959 952 availability.reset(); // Message status flags 960 953 961 954 }; 962 955 … … 969 962 availability.test(bit_L1cphGPS) || 970 963 availability.test(bit_L2cphGPS); 971 964 972 965 }; 973 966 … … 978 971 availability.test(bit_L1cphGLO) || 979 972 availability.test(bit_L2cphGLO); 980 973 981 974 }; 982 975 … … 987 980 availability.test(bit_L1cphGPS) && 988 981 availability.test(bit_L2cphGPS); 989 982 990 983 }; 991 984 … … 996 989 availability.test(bit_L1cphGLO) && 997 990 availability.test(bit_L2cphGLO); 998 991 999 992 }; 1000 993 … … 1004 997 1005 998 return ( allGPS() && ( GPSonly || allGLONASS() ) ); 1006 999 1007 1000 }; 1008 1001 … … 1020 1013 1021 1014 // Check validity and packet type 1022 1023 if ( ! ( P.valid() && 1015 1016 if ( ! ( P.valid() && 1024 1017 (P.ID()==18 || P.ID()==19) ) ) return; 1025 1018 1026 // Check number of data words, message starts with 1 DW for epoch, then each 1027 // satellite brings 2 DW, 1019 // Check number of data words, message starts with 1 DW for epoch, then each 1020 // satellite brings 2 DW, 1028 1021 // Do not start decoding if less than 3 DW are in package 1029 1022 1030 1023 if ( P.nDataWords()<3 ) { 1031 1024 #if ( DEBUG > 0 ) … … 1033 1026 << P.nDataWords() << ") detected" << endl; 1034 1027 #endif 1035 1028 1036 1029 return; 1037 1030 }; 1038 1031 1039 1032 // Check if number of data words is odd number 1040 1033 1041 1034 if ( P.nDataWords()%2==0 ){ 1042 1035 #if ( DEBUG > 0 ) … … 1044 1037 << P.nDataWords() << ") detected" << endl; 1045 1038 #endif 1046 1039 1047 1040 return; 1048 1041 }; 1049 1042 1050 1043 // Clear previous data if block was already complete 1051 1044 1052 1045 if (valid()) clear(); 1053 1054 // Process carrier phase message 1055 1056 if ( P.ID()==18 ) { 1057 1046 1047 // Process carrier phase message 1048 1049 if ( P.ID()==18 ) { 1050 1058 1051 // Number of satellites in current message 1059 NSat = (P.nDataWords()-1)/2; 1060 1061 // Current epoch (mod 3600 sec) 1062 t = 0.6*P.modZCount() 1052 NSat = (P.nDataWords()-1)/2; 1053 1054 // Current epoch (mod 3600 sec) 1055 t = 0.6*P.modZCount() 1063 1056 + P.getUnsignedBits(4,20)*1.0e-6; 1064 1057 1065 1058 #if (ROUND_EPOCH==1) 1066 1059 // SC-104 V2.3 4-42 Note 1 4. Assume measurements at hard edges … … 1075 1068 isOth = ( P.getUnsignedBits(1,1)==1 ); 1076 1069 if (isOth) return; 1077 1070 1078 1071 // Constellation (for first satellite in message) 1079 1072 isGPS = ( P.getUnsignedBits(26,1)==0 ); 1080 1073 GPSonly = GPSonly && isGPS; 1081 1074 1082 1075 // Multiple Message Indicator (only checked for first satellite) 1083 1076 // pendingMsg = ( P.getUnsignedBits(24,1)==1 ); 1084 1085 // Handle epoch: store epoch of first GPS message and 1077 1078 // Handle epoch: store epoch of first GPS message and 1086 1079 // check consistency of subsequent messages. GLONASS time tags 1087 1080 // are different and have to be ignored 1088 1081 if (isGPS) { 1089 1082 if ( nSat==0 ) { 1090 secs = t; // Store epoch 1083 secs = t; // Store epoch 1091 1084 } 1092 1085 // else if (t!=secs) { 1093 1086 else if (abs(t-secs)>1e-6) { 1094 clear(); secs = t; // Clear all data, then store epoch 1087 clear(); secs = t; // Clear all data, then store epoch 1095 1088 }; 1096 1089 }; 1097 1090 1098 // Discard GLONASS observations if no prior GPS observations 1099 // are available 1091 // Discard GLONASS observations if no prior GPS observations 1092 // are available 1100 1093 if (!isGPS && !anyGPS() ) return; 1101 1094 1102 1095 // Set availability flags 1103 1096 1104 1097 if ( isL1 && isGPS) availability.set(bit_L1cphGPS); 1105 1098 if (!isL1 && isGPS) availability.set(bit_L2cphGPS); 1106 1099 if ( isL1 && !isGPS) availability.set(bit_L1cphGLO); 1107 1100 if (!isL1 && !isGPS) availability.set(bit_L2cphGLO); 1108 1101 1109 1102 #if ( DEBUG > 0 ) 1110 cerr << "RTCM2_Obs::extract(): availability " 1111 << bitset<8>(availability) << endl; 1112 #endif 1113 1114 1103 cerr << "RTCM2_Obs::extract(): availability " 1104 << bitset<8>(availability) << endl; 1105 #endif 1106 1107 1115 1108 // Process all satellites 1116 1109 1117 1110 for (int iSat=0;iSat<NSat;iSat++){ 1118 1111 1119 1112 // Code type 1120 1113 isCAcode = ( P.getUnsignedBits(iSat*48+25,1)==0 ); 1121 1122 // Satellite 1114 1115 // Satellite 1123 1116 sid = P.getUnsignedBits(iSat*48+27,5); 1124 1117 if (sid==0) sid=32; 1125 1118 1126 1119 prn = (isGPS? sid : sid+200 ); 1127 1120 1128 1121 // Carrier phase measurement (mod 2^23 [cy]; sign matched to range) 1129 1122 cph = -P.getBits(iSat*48+40,32)/256.0; … … 1149 1142 slip_L2.push_back(-1); 1150 1143 }; 1151 1144 1152 1145 // Store measurement 1153 1146 if (isL1) { … … 1159 1152 slip_L2[idx] = slip_cnt; 1160 1153 }; 1161 1154 1162 1155 }; 1163 1164 }; 1165 1166 1167 // Process pseudorange message 1168 1169 if ( P.ID()==19 ) { 1170 1156 1157 }; 1158 1159 1160 // Process pseudorange message 1161 1162 if ( P.ID()==19 ) { 1163 1171 1164 // Number of satellites in current message 1172 NSat = (P.nDataWords()-1)/2; 1173 1174 // Current epoch (mod 3600 sec) 1175 t = 0.6*P.modZCount() 1165 NSat = (P.nDataWords()-1)/2; 1166 1167 // Current epoch (mod 3600 sec) 1168 t = 0.6*P.modZCount() 1176 1169 + P.getUnsignedBits(4,20)*1.0e-6; 1177 1170 1178 1171 #if (ROUND_EPOCH==1) 1179 1172 // SC-104 V2.3 4-42 Note 1 4. Assume measurements at hard edges … … 1188 1181 isOth = ( P.getUnsignedBits(1,1)==1 ); 1189 1182 if (isOth) return; 1190 1183 1191 1184 #if (FIX_TRIMBLE_4000SSI==1) 1192 1185 // Fix for data streams originating from TRIMBLE_4000SSI receivers. 1193 1186 // GPS PRN32 is erroneously flagged as GLONASS satellite in the C/A 1194 // pseudorange messages. We therefore use a majority voting to 1187 // pseudorange messages. We therefore use a majority voting to 1195 1188 // determine the true constellation for this message. 1196 1189 // This fix is only required for Trimble4000SSI receivers but can also … … 1202 1195 if(isGPS) nGPS++; 1203 1196 }; 1204 isGPS = (2*nGPS>NSat); 1197 isGPS = (2*nGPS>NSat); 1205 1198 #else 1206 1199 // Constellation (for first satellite in message) … … 1211 1204 // Multiple Message Indicator (only checked for first satellite) 1212 1205 // pendingMsg = ( P.getUnsignedBits(24,1)==1 ); 1213 1214 // Handle epoch: store epoch of first GPS message and 1206 1207 // Handle epoch: store epoch of first GPS message and 1215 1208 // check consistency of subsequent messages. GLONASS time tags 1216 1209 // are different and have to be ignored 1217 1210 if (isGPS) { 1218 1211 if ( nSat==0 ) { 1219 secs = t; // Store epoch 1212 secs = t; // Store epoch 1220 1213 } 1221 1214 // else if (t!=secs) { 1222 1215 else if (abs(t-secs)>1e-6) { 1223 clear(); secs = t; // Clear all data, then store epoch 1216 clear(); secs = t; // Clear all data, then store epoch 1224 1217 }; 1225 1218 }; 1226 1219 1227 // Discard GLONASS observations if no prior GPS observations 1228 // are available 1220 // Discard GLONASS observations if no prior GPS observations 1221 // are available 1229 1222 if (!isGPS && !anyGPS() ) return; 1230 1223 1231 1224 // Set availability flags 1232 1225 if ( isL1 && isGPS) availability.set(bit_L1rngGPS); … … 1236 1229 1237 1230 #if ( DEBUG > 0 ) 1238 cerr << "RTCM2_Obs::extract(): availability " 1239 << bitset<8>(availability) << endl; 1231 cerr << "RTCM2_Obs::extract(): availability " 1232 << bitset<8>(availability) << endl; 1240 1233 #endif 1241 1234 1242 1235 // Process all satellites 1243 1236 1244 1237 for (int iSat=0;iSat<NSat;iSat++){ 1245 1238 1246 1239 // Code type 1247 1240 isCAcode = ( P.getUnsignedBits(iSat*48+25,1)==0 ); 1248 1249 // Satellite 1241 1242 // Satellite 1250 1243 sid = P.getUnsignedBits(iSat*48+27,5); 1251 1244 if (sid==0) sid=32; 1252 1245 prn = (isGPS? sid : sid+200 ); 1253 1246 1254 1247 // Pseudorange measurement [m] 1255 1248 rng = P.getUnsignedBits(iSat*48+40,32)*0.02; … … 1272 1265 slip_L2.push_back(-1); 1273 1266 }; 1274 1267 1275 1268 // Store measurement 1276 1269 if (isL1) { … … 1279 1272 } 1280 1273 else { 1281 rng_P1[idx] = rng; 1274 rng_P1[idx] = rng; 1282 1275 } 1283 1276 } … … 1285 1278 rng_P2[idx] = rng; 1286 1279 }; 1287 1280 1288 1281 }; 1289 1290 }; 1291 1292 }; 1293 1294 // 1295 // Resolution of 2^24 cy carrier phase ambiguity 1282 1283 }; 1284 1285 }; 1286 1287 // 1288 // Resolution of 2^24 cy carrier phase ambiguity 1296 1289 // caused by 32-bit data field restrictions 1297 // 1290 // 1298 1291 // Note: the RTCM standard specifies an ambiguity of +/-2^23 cy. 1299 1292 // However, numerous receivers generate data in the +/-2^22 cy range. … … 1304 1297 1305 1298 //const double ambig = pow(2.0,24); // as per RTCM2 spec 1306 const double ambig = pow(2.0,23); // used by many receivers 1299 const double ambig = pow(2.0,23); // used by many receivers 1307 1300 1308 1301 double rng; 1309 1302 double n; 1310 1303 1311 1304 if (!valid() || i<0 || i>nSat-1) return 0.0; 1312 1305 1313 rng = rng_C1[i]; 1306 rng = rng_C1[i]; 1314 1307 if (rng==0.0) rng = rng_P1[i]; 1315 1308 if (rng==0.0) return 0.0; 1316 1309 1317 1310 n = floor( (rng/lambda_L1-cph_L1[i]) / ambig + 0.5 ); 1318 1311 1319 1312 return cph_L1[i] + n*ambig; 1320 1321 }; 1313 1314 }; 1322 1315 1323 1316 double RTCM2_Obs::resolvedPhase_L2(int i) const { 1324 1317 1325 1318 //const double ambig = pow(2.0,24); // as per RTCM2 spec 1326 const double ambig = pow(2.0,23); // used by many receivers 1319 const double ambig = pow(2.0,23); // used by many receivers 1327 1320 1328 1321 double rng; 1329 1322 double n; 1330 1323 1331 1324 if (!valid() || i<0 || i>nSat-1) return 0.0; 1332 1333 rng = rng_C1[i]; 1325 1326 rng = rng_C1[i]; 1334 1327 if (rng==0.0) rng = rng_P1[i]; 1335 1328 if (rng==0.0) return 0.0; 1336 1329 1337 1330 n = floor( (rng/lambda_L2-cph_L2[i]) / ambig + 0.5 ); 1338 1331 1339 1332 return cph_L2[i] + n*ambig; 1340 1341 }; 1333 1334 }; 1342 1335 1343 1336 // 1344 1337 // Resolution of epoch using reference date (GPS week and secs) 1345 // 1346 1347 void RTCM2_Obs::resolveEpoch (int refWeek, double refSecs, 1338 // 1339 1340 void RTCM2_Obs::resolveEpoch (int refWeek, double refSecs, 1348 1341 int& epochWeek, double& epochSecs ) const { 1349 1342 1350 const double secsPerWeek = 604800.0; 1343 const double secsPerWeek = 604800.0; 1351 1344 1352 1345 epochWeek = refWeek; 1353 1346 epochSecs = secs + 3600.0*(floor((refSecs-secs)/3600.0+0.5)); 1354 1347 1355 1348 if (epochSecs<0 ) { epochWeek--; epochSecs+=secsPerWeek; }; 1356 1349 if (epochSecs>secsPerWeek) { epochWeek++; epochSecs-=secsPerWeek; }; 1357 1350 1358 1351 }; 1359 1352 -
trunk/BNC/src/RTCM/RTCM2.h
r1105 r7629 2 2 // 3 3 // RTCM2.h 4 // 5 // Purpose: 4 // 5 // Purpose: 6 6 // 7 7 // Module for extraction of RTCM2 messages … … 11 11 // RTCM 10402.3 Recommended Standards for Differential GNSS (Global 12 12 // Navigation Satellite Systems) Service; RTCM Paper 136-2001/SC104-STD, 13 // Version 2.3, 20 Aug. 2001; Radio Technical Commission For Maritime 13 // Version 2.3, 20 Aug. 2001; Radio Technical Commission For Maritime 14 14 // Services, Alexandria, Virgina (2001). 15 15 // ICD-GPS-200; Navstar GPS Space Segment / Navigation User Interfaces; … … 38 38 #define INC_RTCM2_H 39 39 40 #include <bitset> 40 #include <bitset> 41 41 #include <fstream> 42 42 #include <string> … … 55 55 // 56 56 // Purpose: 57 // 57 // 58 58 // Handling of RTCM2 30bit words 59 59 // … … 63 63 64 64 public: 65 65 66 66 // Constructor and initialization 67 67 68 68 ThirtyBitWord(); 69 69 70 70 void clear(); 71 71 72 72 // Status queries 73 73 74 74 bool fail() const; 75 75 bool validParity() const; … … 77 77 78 78 // Access methods 79 79 80 80 unsigned int all() const; 81 81 unsigned int value() const; 82 82 83 83 // Input 84 84 85 85 void get(const std::string& buf); 86 86 void get(std::istream& inp); 87 87 void getHeader(std::string& buf); 88 88 void getHeader(std::istream& inp); 89 90 private: 91 89 90 private: 91 92 92 // Input 93 93 … … 102 102 // parity bits retained from the previous word 103 103 // 104 // Bits 31..30 (from left to right) hold the parity bits D29*..D30* of 104 // Bits 31..30 (from left to right) hold the parity bits D29*..D30* of 105 105 // the previous 30-bit word 106 106 // Bits 29..06 (from left to right) hold the current data bits D01..D24 … … 108 108 // 109 109 110 unsigned int W; 111 110 unsigned int W; 111 112 112 }; 113 113 … … 125 125 126 126 class RTCM2packet { 127 128 public: 129 127 128 public: 129 130 130 // Constructor and initialization 131 131 132 132 RTCM2packet(); 133 133 134 134 void clear(); 135 135 136 136 // Status queries 137 137 138 bool valid() const; 139 140 // Input 138 bool valid() const; 139 140 // Input 141 141 142 142 void getPacket(std::string& buf); 143 143 void getPacket(std::istream& inp); 144 144 friend std::istream& operator >> (std::istream& is, RTCM2packet& p); 145 145 146 146 // 147 147 // Access methods 148 // 149 148 // 149 150 150 // Header and data words contents (parity corrected) 151 151 152 152 unsigned int header1() const; 153 153 unsigned int header2() const; 154 154 unsigned int dataWord(int i) const; 155 155 156 156 // Header information 157 157 158 158 unsigned int msgType() const; 159 159 unsigned int ID() const { return msgType(); }; … … 174 174 175 175 // All input of RTCM data uses a single instance, W, of a 30-bit word 176 // to maintain parity bits between consecutive inputs. 177 176 // to maintain parity bits between consecutive inputs. 177 178 178 ThirtyBitWord W; 179 179 180 180 // Two 30-bit words make up the header of an RTCM2 message 181 // (parity corrected) 182 181 // (parity corrected) 182 183 183 unsigned int H1; 184 184 unsigned int H2; … … 187 187 188 188 std::vector<unsigned int> DW; 189 190 }; 189 190 }; 191 191 192 192 … … 202 202 203 203 class RTCM2_03 { 204 204 205 205 public: 206 206 // Constructor 207 RTCM2_03(); 208 207 RTCM2_03() { 208 validMsg = false; 209 x = 0.0; 210 y = 0.0; 211 z = 0.0; 212 } 209 213 void extract(const RTCM2packet& P); 210 211 public:212 213 214 bool validMsg; // Validity flag 214 215 double x,y,z; // Station coordinates … … 230 231 231 232 public: 232 233 RTCM2_23 () { 234 validMsg = false; 235 } 233 236 void extract(const RTCM2packet& P); 234 235 public:236 237 237 bool validMsg; // Validity flag 238 238 std::string antType; // Antenna descriptor … … 248 248 // Purpose: 249 249 // 250 // A class for handling RTCM 2 Reference Station Antenna 250 // A class for handling RTCM 2 Reference Station Antenna 251 251 // Reference Point Parameter messages 252 252 // … … 256 256 257 257 public: 258 258 RTCM2_24 () { 259 validMsg = false; 260 isGPS = false; 261 isGLONASS = false; 262 x = 0.0; 263 y = 0.0; 264 z = 0.0; 265 h = 0.0; 266 } 259 267 void extract(const RTCM2packet& P); 260 261 public:262 263 268 bool validMsg; // Validity flag 264 269 bool isGPS; // Flag for GPS supporting station … … 277 282 // Purpose: 278 283 // 279 // A class for handling blocks of RTCM2 18 & 19 packets that need to be 284 // A class for handling blocks of RTCM2 18 & 19 packets that need to be 280 285 // combined to get a complete set of measurements 281 286 // … … 284 289 class RTCM2_Obs { 285 290 286 public: 291 public: 287 292 288 293 RTCM2_Obs(); // Constructor 289 294 290 295 void extract(const RTCM2packet& P); // Packet handler 291 296 void clear(); // Initialization 292 bool valid() const; // Check for complete obs block 297 bool valid() const; // Check for complete obs block 293 298 294 299 double resolvedPhase_L1(int i) const; // L1 & L2 carrier phase of i-th sat 295 double resolvedPhase_L2(int i) const; // with resolved 2^24 cy ambiguity 300 double resolvedPhase_L2(int i) const; // with resolved 2^24 cy ambiguity 296 301 // (based on rng_C1) 297 302 … … 300 305 int& epochWeek, 301 306 double& epochSecs ) const; 302 303 304 public: 307 308 309 public: 305 310 306 311 double secs; // Seconds of hour (GPS time) … … 325 330 326 331 typedef std::bitset<8> msgflags; 327 332 328 333 msgflags availability; // Msg availability flags 329 334 bool GPSonly; // Flag for GPS-only station 330 335 331 }; 336 }; 332 337 333 338 -
trunk/BNC/src/RTCM/RTCM2_2021.cpp
r2588 r7629 10 10 const double ZEROVALUE = 1e-100; 11 11 12 RTCM2_2021::RTCM2_2021() { }13 14 12 15 13 void RTCM2_2021::extract(const RTCM2packet& P) { … … 18 16 } 19 17 20 // Error: at least 4 data words 18 // Error: at least 4 data words 21 19 if ( P.nDataWords()<5 ) { 22 20 #if ( DEBUG > 0 ) … … 26 24 return; 27 25 }; 28 26 29 27 // Error: number of data words has to be odd number 30 28 if ( P.nDataWords()%2==0 ){ … … 36 34 }; 37 35 38 // Current epoch (mod 3600 sec) 39 double tt = 0.6*P.modZCount() 36 // Current epoch (mod 3600 sec) 37 double tt = 0.6*P.modZCount() 40 38 + P.getUnsignedBits(4,20)*1.0e-6; 41 39 … … 59 57 double multipleMsgInd = true; 60 58 for (unsigned iSat = 0; iSat < nSat; iSat++) { 61 bool multInd = P.getBits (iSat*48 + 24, 1); 59 bool multInd = P.getBits (iSat*48 + 24, 1); 62 60 bool isGPS = ( P.getUnsignedBits(iSat*48 + 26, 1)==0 ); 63 61 unsigned PRN = P.getUnsignedBits(iSat*48 + 27, 5); … … 71 69 PRN = 32; 72 70 } 73 71 74 72 HiResCorr* corr = 0; 75 73 if ( !(corr = find_i(PRN)) ) { … … 80 78 data[PRN] = corr; 81 79 } 82 80 83 81 corr->PRN = PRN; 84 82 corr->tt = tt_; … … 106 104 // Message number 21 107 105 else if ( P.ID() == 21 ) { 108 bool P_CA_Ind = P.getBits (iSat*48 + 25, 1); 106 bool P_CA_Ind = P.getBits (iSat*48 + 25, 1); 109 107 double dcorrUnit = ( P.getUnsignedBits(iSat*48 + 32, 1) ? 0.032 : 0.002); 110 108 double corrUnit = ( P.getUnsignedBits(iSat*48 + 36, 1) ? 0.320 : 0.020); … … 127 125 } 128 126 } 129 127 130 128 valid_ = !multipleMsgInd; 131 129 } … … 146 144 tt_ = 0; 147 145 valid_ = false; 148 for (map<unsigned, HiResCorr>::iterator 146 for (map<unsigned, HiResCorr>::iterator 149 147 ii = data_i_.begin(); ii != data_i_.end(); ii++) { 150 148 ii->second.reset(); … … 155 153 156 154 RTCM2_2021::HiResCorr::HiResCorr() : 157 PRN(0), tt(0), 155 PRN(0), tt(0), 158 156 phase1 (0), phase2 (2), 159 157 lock1 (0), lock2 (0), … … 163 161 drange1(0), drange2(0), 164 162 Pind1 (false), Pind2 (false), 165 IODr1 (0), IODr2 (0) { 163 IODr1 (0), IODr2 (0) { 166 164 } 167 165 -
trunk/BNC/src/RTCM/RTCM2_2021.h
r7628 r7629 8 8 9 9 public: 10 11 RTCM2_2021(); // Constructor 10 RTCM2_2021() {// Constructor 11 tt_ = 0.0; 12 valid_ = false; 13 } 12 14 13 15 void extract(const RTCM2packet& P); // Packet handler … … 18 20 double resolvedPhase_L2(int i) const; // with resolved 2^24 cy ambiguity 19 21 // (based on rng_C1) 20 21 public:22 22 23 23 struct HiResCorr {
Note:
See TracChangeset
for help on using the changeset viewer.