00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <windows.h>
00038 #include <process.h>
00039 #include <math.h>
00040 #include <string>
00041 #include <time.h>
00042 #include <queue>
00043 #include "SerialPortClass.h"
00044 #include "novatel.h"
00045 #include "time_conversion.h"
00046 #include "gpsppssync_OptionFile.h"
00047 #include "gnss_error.h"
00048
00049 #define PACKET_SIZE (16384)
00050 #define BIG_BUFFER_SIZE (1024*1024) // 1 MB
00051
00052 using namespace std;
00053
00054
00055 struct stUTC
00056 {
00057 unsigned short year;
00058 unsigned char month;
00059 unsigned char day;
00060 unsigned char hour;
00061 unsigned char minute;
00062 float seconds;
00063
00064 stUTC(): year(0), month(0), day(0), hour(0), minute(0), seconds(0.0){}
00065 };
00066
00067 struct stPCTime
00068 {
00069 unsigned short utc_year;
00070 unsigned char utc_month;
00071 unsigned char utc_day;
00072 unsigned char utc_hour;
00073 unsigned char utc_minute;
00074 float utc_seconds;
00075 unsigned char utc_offset;
00076 unsigned short gps_week;
00077 double gps_tow;
00078 double jd;
00079 };
00080
00081
00082
00083
00084
00085
00086 bool PerformGPSPCTimeSync_NovAtelOEM3(
00087 const unsigned SerialPortNumber,
00088 const unsigned SerialPortNumberOnReceiver,
00089 const bool PerformPPSTest,
00090 const bool AllowTimeForHyperTerminalComparison
00091 );
00092
00093
00094
00095
00096 bool PerformGPSPCTimeSync_NovAtelOEM4(
00097 const unsigned SerialPortNumber,
00098 const unsigned SerialPortNumberOnReceiver,
00099 const bool PerformPPSTest,
00100 const bool AllowTimeForHyperTerminalComparison
00101 );
00102
00103
00104
00105 bool SendCommand( SerialPort& port, std::string msg );
00106
00107
00108 int main( int argc, char* argv[] )
00109 {
00110 try
00111 {
00112 gpsppssync_OptionFile opt;
00113 char buffer[8192];
00114 unsigned i = 0;
00115
00116
00117 memset( buffer, 0, 512 );
00118
00119
00120 if( argc != 2 )
00121 {
00122 printf( "USAGE: gpsppssync <option filename>\n" );
00123 return 0;
00124 }
00125
00126
00127 if( !opt.ReadAndInterpretOptions( argv[1] ) )
00128 {
00129 printf( "opt.ReadFromFile returned false.\n" );
00130 return -1;
00131 }
00132
00133 if( opt.m_ReceiverType.compare( "NOVATELOEM3" ) == 0 )
00134 {
00135 if( !PerformGPSPCTimeSync_NovAtelOEM3( opt.m_SerialPortNumber, opt.m_ReceiverSerialPortNumber, opt.m_PerformPPSTest, opt.m_AllowTimeForHyperTerminalComparison ) )
00136 {
00137 printf( "PerformGPSPCTimeSync_NovAtelOEM3 returned false.\n" );
00138 return -1;
00139 }
00140 }
00141 else if( opt.m_ReceiverType.compare( "NOVATELOEM4" ) == 0 || opt.m_ReceiverType.compare( "NOVATELOEMV" ) == 0 )
00142 {
00143 if( !PerformGPSPCTimeSync_NovAtelOEM4( opt.m_SerialPortNumber, opt.m_ReceiverSerialPortNumber, opt.m_PerformPPSTest, opt.m_AllowTimeForHyperTerminalComparison ) )
00144 {
00145 printf( "PerformGPSPCTimeSync_NovAtelOEM4 returned false.\n" );
00146 return -1;
00147 }
00148 }
00149
00150 printf( "Shutting down.\n" );
00151 Sleep(1500);
00152 }
00153 catch( ... )
00154 {
00155
00156 }
00157 return 0;
00158 }
00159
00160
00161
00162 bool PerformGPSPCTimeSync_NovAtelOEM3(
00163 const unsigned SerialPortNumber,
00164 const unsigned SerialPortNumberOnReceiver,
00165 const bool PerformPPSTest,
00166 const bool AllowTimeForHyperTerminalComparison
00167 )
00168 {
00169 SerialPort port;
00170 unsigned char readbuf[PACKET_SIZE];
00171 unsigned char buffer[PACKET_SIZE];
00172 unsigned char message[PACKET_SIZE];
00173 unsigned messageLength = 0;
00174 unsigned nrBytesRead = 0;
00175 unsigned nrBytesInBuffer = 0;
00176 unsigned offset = 0;
00177 BOOL result = 0;
00178 BOOL wasEndOfBufferReached = FALSE;
00179 BOOL wasMessageFound = FALSE;
00180 unsigned startPosition = 0;
00181 unsigned messageID = 0;
00182 unsigned nrBadCheckums = 0;
00183 int method = 0;
00184 unsigned count = 0;
00185 unsigned i = 0;
00186 std::string msg;
00187
00188 stUTC utc;
00189
00190 double rs232_transmission_time = 0;
00191
00192 stPCTime pc_time;
00193
00194
00195 struct
00196 {
00197 unsigned short gps_week;
00198 double gps_tow;
00199 double lat;
00200 double lon;
00201 double hgt;
00202 double lat_std;
00203 double lon_std;
00204 double hgt_std;
00205 double undulation;
00206 unsigned datum_id;
00207 NOVATELOEM3_enumSolutionStatus status;
00208 } posb;
00209
00210
00211 struct
00212 {
00213 unsigned short gps_week;
00214 double gps_tow;
00215 double clk_offset;
00216 double clk_offset_std;
00217 double utc_offset;
00218 BOOL is_clk_stabilized;
00219 } tm1b;
00220
00221 clock_t c0;
00222 clock_t c1;
00223 double elapsed_time_s = 0;
00224 bool isPositionValid = false;
00225
00226 bool coarse_sync_success = false;
00227 bool pps_sync_success = false;
00228 bool ring_detected = false;
00229 bool wasDataReceived = false;
00230 unsigned pulse_count = 0;
00231
00232
00233
00234
00235 SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS );
00236 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );
00237
00238 if( !port.Open( (unsigned short)SerialPortNumber, SERIALPORT_BAUD_115200 ) )
00239 {
00240 printf( "Unable to open port %d.", SerialPortNumber );
00241 return false;
00242 }
00243 Sleep(50);
00244
00245 printf( "Performing GPS - PC time synchronization.\n" );
00246
00247 sprintf( (char*)message, "unlogall COM%d\r", SerialPortNumberOnReceiver );
00248 msg = (char*)message;
00249 SendCommand( port, msg );
00250
00251
00252 sprintf( (char*)message, "log com%d POSB ontime 2.0\r", SerialPortNumberOnReceiver );
00253 msg = (char*)message;
00254 SendCommand( port, msg );
00255
00256
00257 memset( readbuf, 0, PACKET_SIZE );
00258 if( !port.Read( readbuf, PACKET_SIZE, nrBytesRead ) )
00259 {
00260 printf( "port.Read returned false. port %d.\n", SerialPortNumber );
00261 return false;
00262 }
00263 if( !port.Read( readbuf, PACKET_SIZE, nrBytesRead ) )
00264 {
00265 printf( "port.Read returned false. port %d.\n", SerialPortNumber );
00266 return false;
00267 }
00268
00269 c0 = clock();
00270 while( elapsed_time_s < 30.0 && isPositionValid == false )
00271 {
00272 memset( readbuf, 0, PACKET_SIZE );
00273 if( !port.Read( readbuf, PACKET_SIZE, nrBytesRead ) )
00274 {
00275 printf( "port.Read returned false. port %d.\n", SerialPortNumber );
00276 return false;
00277 }
00278
00279 if( nrBytesRead > 0 )
00280 {
00281 printf( "%d bytes read.\n", nrBytesRead );
00282 if( nrBytesRead + offset > PACKET_SIZE )
00283 {
00284 printf( "Unexpected.\n");
00285 return false;
00286 }
00287 memcpy( buffer+offset, readbuf, nrBytesRead );
00288 nrBytesInBuffer += nrBytesRead;
00289 offset = nrBytesInBuffer;
00290
00291 if( nrBytesInBuffer > 12 )
00292 {
00293 result = NOVATELOEM3_FindNextMessageInBuffer(
00294 buffer,
00295 PACKET_SIZE,
00296 message,
00297 PACKET_SIZE,
00298 &wasEndOfBufferReached,
00299 &wasMessageFound,
00300 &startPosition,
00301 &messageLength,
00302 &messageID,
00303 &nrBadCheckums
00304 );
00305 }
00306
00307 if( wasMessageFound && messageID == NOVATELOEM3_POSB )
00308 {
00309 result = NOVATELOEM3_DecodePOSB(
00310 message,
00311 messageLength,
00312 &posb.gps_week,
00313 &posb.gps_tow,
00314 &posb.lat,
00315 &posb.lon,
00316 &posb.hgt,
00317 &posb.undulation,
00318 &posb.datum_id,
00319 &posb.lat_std,
00320 &posb.lon_std,
00321 &posb.hgt_std,
00322 &posb.status
00323 );
00324
00325 if( posb.status == NOVATELOEM3_SOLUTIONSTATUS_OK )
00326 {
00327 isPositionValid = true;
00328 continue;
00329 }
00330 else
00331 {
00332 offset = 0;
00333 }
00334 }
00335 else
00336 {
00337 offset = 0;
00338
00339 }
00340 }
00341 Sleep(60);
00342 c1 = clock();
00343 elapsed_time_s = ((double)(c1-c0))/((double)CLOCKS_PER_SEC);
00344 }
00345
00346 if( !isPositionValid )
00347 {
00348 printf( "The receiver position is not yet valid. Try again.\n" );
00349 return true;
00350 }
00351 else
00352 {
00353 printf( "A valid receiver position was verified.\n" );
00354 }
00355
00356
00357 sprintf( (char*)message, "unlogall com%d\r", SerialPortNumberOnReceiver );
00358 msg = (char*)message;
00359 SendCommand( port, msg );
00360
00361 sprintf( (char*)message, "log com%d TM1B ontime 5.0\r", SerialPortNumberOnReceiver );
00362 msg = (char*)message;
00363 SendCommand( port, msg );
00364 Sleep(1500);
00365
00366
00367 if( !port.Read( readbuf, PACKET_SIZE, nrBytesRead ) )
00368 {
00369 printf( "port.Read returned false. port %d.\n", SerialPortNumber );
00370 return false;
00371 }
00372 if( !port.Read( readbuf, PACKET_SIZE, nrBytesRead ) )
00373 {
00374 printf( "port.Read returned false. port %d.\n", SerialPortNumber );
00375 return false;
00376 }
00377
00378 coarse_sync_success = false;
00379 tm1b.is_clk_stabilized = FALSE;
00380 c0 = clock();
00381 elapsed_time_s = 0;
00382 while( elapsed_time_s < 30.0 && coarse_sync_success == false )
00383 {
00384 memset( readbuf, 0, PACKET_SIZE );
00385 if( !port.Read( readbuf, PACKET_SIZE, nrBytesRead ) )
00386 {
00387 printf( "port.Read returned false. port %d.\n", SerialPortNumber );
00388 return false;
00389 }
00390
00391 if( nrBytesRead > 0 )
00392 {
00393 printf( "%d bytes read.\n", nrBytesRead );
00394 if( nrBytesRead + offset > PACKET_SIZE )
00395 {
00396 printf( "Unexpected.\n");
00397 return false;
00398 }
00399 memcpy( buffer+offset, readbuf, nrBytesRead );
00400 nrBytesInBuffer += nrBytesRead;
00401 offset = nrBytesInBuffer;
00402
00403 if( nrBytesInBuffer > 12 )
00404 {
00405 result = NOVATELOEM3_FindNextMessageInBuffer(
00406 buffer,
00407 PACKET_SIZE,
00408 message,
00409 PACKET_SIZE,
00410 &wasEndOfBufferReached,
00411 &wasMessageFound,
00412 &startPosition,
00413 &messageLength,
00414 &messageID,
00415 &nrBadCheckums
00416 );
00417 }
00418
00419 if( wasMessageFound && messageID == NOVATELOEM3_TM1B )
00420 {
00421 result = NOVATELOEM3_DecodeTM1B(
00422 message,
00423 messageLength,
00424 &tm1b.gps_week,
00425 &tm1b.gps_tow,
00426 &tm1b.clk_offset,
00427 &tm1b.clk_offset_std,
00428 &tm1b.utc_offset,
00429 &tm1b.is_clk_stabilized
00430 );
00431
00432 if( tm1b.is_clk_stabilized )
00433 {
00434 tm1b.gps_week += 1024;
00435 result = TIMECONV_GetUTCTimeFromGPSTime(
00436 tm1b.gps_week,
00437 tm1b.gps_tow,
00438 &utc.year,
00439 &utc.month,
00440 &utc.day,
00441 &utc.hour,
00442 &utc.minute,
00443 &utc.seconds
00444 );
00445 if( !result )
00446 {
00447 printf( "TIMECONV_GetUTCTimeFromGPSTime returned false.\n" );
00448 return false;
00449 }
00450
00451 rs232_transmission_time = messageLength * 9.0 / 115200.0;
00452
00453 utc.seconds -= (float)rs232_transmission_time;
00454
00455 if( utc.seconds < 0 )
00456 {
00457 utc.seconds += 60.0;
00458 if( utc.minute == 0 )
00459 {
00460 utc.minute = 59;
00461 if( utc.hour == 0 )
00462 {
00463 printf( "Too close to midnight to proceed.\n" );
00464 return true;
00465 }
00466 else
00467 {
00468 utc.hour--;
00469 }
00470 }
00471 else
00472 {
00473 utc.minute--;
00474 }
00475 }
00476
00477
00478 result = TIMECONV_SetSystemTime(
00479 utc.year,
00480 utc.month,
00481 utc.day,
00482 utc.hour,
00483 utc.minute,
00484 utc.seconds
00485 );
00486
00487 if( !result )
00488 {
00489 printf("TIMECONV_SetSystemTime returned FALSE.");
00490 return false;
00491 }
00492 else
00493 {
00494 printf( "Coarse synchronization performed using TM1B message.\n" );
00495 coarse_sync_success = true;
00496 continue;
00497 }
00498 }
00499 else
00500 {
00501 offset = 0;
00502 }
00503 }
00504 else
00505 {
00506 offset = 0;
00507 }
00508 }
00509 Sleep(5);
00510 c1 = clock();
00511 elapsed_time_s = ((double)(c1-c0))/((double)CLOCKS_PER_SEC);
00512 }
00513
00514 if( !coarse_sync_success )
00515 {
00516 printf( "Unable to achieve coarse synchronization. Please try again.\n" );
00517 return false;
00518 }
00519
00520 sprintf( (char*)message, "unlogall com%d\r", SerialPortNumberOnReceiver );
00521 msg = (char*)message;
00522 SendCommand( port, msg );
00523
00524
00525 c0 = clock();
00526 elapsed_time_s = 0;
00527 while( elapsed_time_s < 30.0 && pps_sync_success == false )
00528 {
00529 double seconds = 0;
00530 port.WaitOnRingIndicator( 990, ring_detected );
00531 if( ring_detected )
00532 {
00533 result = TIMECONV_GetSystemTime(
00534 &pc_time.utc_year,
00535 &pc_time.utc_month,
00536 &pc_time.utc_day,
00537 &pc_time.utc_hour,
00538 &pc_time.utc_minute,
00539 &pc_time.utc_seconds,
00540 &pc_time.utc_offset,
00541 &pc_time.jd,
00542 &pc_time.gps_week,
00543 &pc_time.gps_tow
00544 );
00545 if( !result )
00546 {
00547 printf( "TIMECONV_GetSystemTime return false." );
00548 return false;
00549 }
00550 seconds = pc_time.utc_seconds;
00551
00552 pc_time.utc_seconds = floor( pc_time.utc_seconds + 1 );
00553 if( pc_time.utc_seconds == 60 )
00554 {
00555 pc_time.utc_seconds = 0;
00556 pc_time.utc_minute++;
00557 if( pc_time.utc_minute == 60 )
00558 {
00559 pc_time.utc_minute = 0;
00560 pc_time.utc_hour++;
00561 if( pc_time.utc_hour == 24 )
00562 {
00563 printf( "Too close to midnight to proceed\n" );
00564 return false;
00565 }
00566 }
00567 }
00568
00569 pulse_count++;
00570 if( pulse_count == 5 )
00571 {
00572 result = TIMECONV_SetSystemTime(
00573 pc_time.utc_year,
00574 pc_time.utc_month,
00575 pc_time.utc_day,
00576 pc_time.utc_hour,
00577 pc_time.utc_minute,
00578 floor(pc_time.utc_seconds)
00579 );
00580 if( !result )
00581 {
00582 printf( "TIMECONV_GetSystemTime return false." );
00583 return false;
00584 }
00585 else
00586 {
00587 pps_sync_success = true;
00588 }
00589 }
00590 else
00591 {
00592 printf( "Pulse detected: Synchronizing in %d s.\n", 5-pulse_count );
00593 }
00594 }
00595 else
00596 {
00597 printf( "%.0fs Remaining. Listening pin 9, ring indicator pin, of COM%d for PPS\n", 30.0 - elapsed_time_s, port.GetPortNumber() );
00598 }
00599 c1 = clock();
00600 elapsed_time_s = ((double)(c1-c0))/((double)CLOCKS_PER_SEC);
00601 }
00602
00603 if( pps_sync_success )
00604 {
00605 printf( "Sync to PPS successful.\n" );
00606 }
00607 else
00608 {
00609 printf( "Failted to sync to PPS. Please try again.\n" );
00610 return true;
00611 }
00612
00613 double mean_diff = 0;
00614 if( PerformPPSTest )
00615 {
00616 int pulsenr = 0;
00617 bool initc2 = true;
00618 clock_t c2;
00619 clock_t c3;
00620 double dt = 0;
00621 double diff = 0;
00622
00623 printf( "Performing PPS test.\n" );
00624
00625
00626 c0 = clock();
00627 elapsed_time_s = 0;
00628 while( elapsed_time_s < 60.0 )
00629 {
00630 port.WaitOnRingIndicator( 1005, ring_detected );
00631 if( ring_detected )
00632 {
00633 if( initc2 )
00634 {
00635 c3 = c2 = clock();
00636 initc2 = false;
00637 }
00638 else
00639 {
00640 c3 = clock();
00641 }
00642 result = TIMECONV_GetSystemTime(
00643 &pc_time.utc_year,
00644 &pc_time.utc_month,
00645 &pc_time.utc_day,
00646 &pc_time.utc_hour,
00647 &pc_time.utc_minute,
00648 &pc_time.utc_seconds,
00649 &pc_time.utc_offset,
00650 &pc_time.jd,
00651 &pc_time.gps_week,
00652 &pc_time.gps_tow
00653 );
00654 if( !result )
00655 {
00656 printf( "TIMECONV_GetSystemTime return false." );
00657 return false;
00658 }
00659 dt = ((double)(c3-c2))/((double)CLOCKS_PER_SEC);
00660 if( pc_time.gps_tow - floor( pc_time.gps_tow ) > 0.5 )
00661 diff = -(floor( pc_time.gps_tow + 0.5 ) - pc_time.gps_tow)*1000.0;
00662 else
00663 diff = (pc_time.gps_tow - floor( pc_time.gps_tow ))*1000.0;
00664
00665 mean_diff += diff;
00666
00667 printf( "Pulse:%2d, dt:%.3f, PC(hh:mm:ss.sss): %02d:%02d:%06.3f difference:%.0f ms\n", pulsenr, dt, pc_time.utc_hour, pc_time.utc_minute, pc_time.utc_seconds, diff );
00668 pulsenr++;
00669 }
00670 else
00671 {
00672 printf( "No ring.\n" );
00673 }
00674 c1 = clock();
00675 elapsed_time_s = ((double)(c1-c0))/((double)CLOCKS_PER_SEC);
00676 }
00677 printf( "Over 60 seconds, the difference in elapsed PC time is %.3f s\n", dt-60.0 );
00678 mean_diff/= (double)pulsenr;
00679 printf( "The mean pulse to pc time difference is: %.3f ms\n", mean_diff );
00680 }
00681
00682
00683 if( AllowTimeForHyperTerminalComparison )
00684 {
00685 sprintf( (char*)message, "log com%d gpzda ontime 1.0\r", SerialPortNumberOnReceiver );
00686 msg = (char*)message;
00687 SendCommand( port, msg );
00688
00689 sprintf( (char*)message, "log com%d posa ontime 1.0\r", SerialPortNumberOnReceiver );
00690 msg = (char*)message;
00691 SendCommand( port, msg );
00692 }
00693
00694 port.Close();
00695
00696
00697 if( AllowTimeForHyperTerminalComparison )
00698 {
00699 printf( "The serial port is now closed you may open the port with hyperterminal for comparison.\n" );
00700 if( pps_sync_success )
00701 {
00702 count = 0;
00703 while( count < 40 )
00704 {
00705 TIMECONV_GetSystemTime(
00706 &pc_time.utc_year,
00707 &pc_time.utc_month,
00708 &pc_time.utc_day,
00709 &pc_time.utc_hour,
00710 &pc_time.utc_minute,
00711 &pc_time.utc_seconds,
00712 &pc_time.utc_offset,
00713 &pc_time.jd,
00714 &pc_time.gps_week,
00715 &pc_time.gps_tow
00716 );
00717 if( fabs(pc_time.utc_seconds - floor(pc_time.utc_seconds)) < 0.05 )
00718 {
00719 printf( "%02d:%02d:%.3f\t\t\t %d %.3f\n", pc_time.utc_hour, pc_time.utc_minute, pc_time.utc_seconds, pc_time.gps_week, pc_time.gps_tow );
00720 printf( "\a" );
00721 count++;
00722 Sleep(980);
00723 }
00724 Sleep(2);
00725 }
00726 }
00727 }
00728
00729 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS );
00730 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL );
00731
00732 return true;
00733 }
00734
00735
00736 bool PerformGPSPCTimeSync_NovAtelOEM4(
00737 const unsigned SerialPortNumber,
00738 const unsigned SerialPortNumberOnReceiver,
00739 const bool PerformPPSTest,
00740 const bool AllowTimeForHyperTerminalComparison
00741 )
00742 {
00743 SerialPort port;
00744 unsigned char readbuf[PACKET_SIZE];
00745 unsigned char buffer[PACKET_SIZE];
00746 unsigned char message[PACKET_SIZE];
00747 unsigned short messageLength = 0;
00748 unsigned nrBytesRead = 0;
00749 unsigned nrBytesInBuffer = 0;
00750 unsigned offset = 0;
00751 BOOL result = 0;
00752 BOOL wasEndOfBufferReached = FALSE;
00753 BOOL wasMessageFound = FALSE;
00754 unsigned startPosition = 0;
00755 unsigned short messageID = 0;
00756 unsigned nrBadCRC = 0;
00757 int method = 0;
00758 unsigned count = 0;
00759 unsigned i = 0;
00760 std::string msg;
00761
00762 stUTC utc;
00763
00764 double rs232_transmission_time = 0;
00765
00766 stPCTime pc_time;
00767
00768 NOVATELOEM4_structBinaryHeader header;
00769 NOVATELOEM4_structBestPosition bestpos;
00770 NOVATELOEM4_structTime time_data;
00771
00772 clock_t c0;
00773 clock_t c1;
00774 double elapsed_time_s = 0;
00775 bool isPositionValid = false;
00776
00777 bool coarse_sync_success = false;
00778 bool pps_sync_success = false;
00779 bool ring_detected = false;
00780 bool wasDataReceived = false;
00781 unsigned pulse_count = 0;
00782
00783
00784
00785
00786 SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS );
00787 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );
00788
00789 if( !port.Open( (unsigned short)SerialPortNumber, SERIALPORT_BAUD_115200 ) )
00790 {
00791 printf( "Unable to open port %d.", SerialPortNumber );
00792 return false;
00793 }
00794 Sleep(50);
00795
00796 printf( "Performing GPS - PC time synchronization.\n" );
00797
00798 sprintf( (char*)message, "unlogall COM%d_ALL\r", SerialPortNumberOnReceiver );
00799 msg = (char*)message;
00800 SendCommand( port, msg );
00801
00802
00803 sprintf( (char*)message, "log com%d BESTPOSB ontime 2.0\r", SerialPortNumberOnReceiver );
00804 msg = (char*)message;
00805 SendCommand( port, msg );
00806 Sleep(1500);
00807
00808
00809 if( !port.Read( readbuf, PACKET_SIZE, nrBytesRead ) )
00810 {
00811 printf( "port.Read returned false. port %d.\n", SerialPortNumber );
00812 return false;
00813 }
00814 if( !port.Read( readbuf, PACKET_SIZE, nrBytesRead ) )
00815 {
00816 printf( "port.Read returned false. port %d.\n", SerialPortNumber );
00817 return false;
00818 }
00819
00820 c0 = clock();
00821 while( elapsed_time_s < 30.0 && isPositionValid == false )
00822 {
00823 memset( readbuf, 0, PACKET_SIZE );
00824 if( !port.Read( readbuf, PACKET_SIZE, nrBytesRead ) )
00825 {
00826 printf( "port.Read returned false. port %d.\n", SerialPortNumber );
00827 return false;
00828 }
00829
00830 if( nrBytesRead > 0 )
00831 {
00832 printf( "%d bytes read.\n", nrBytesRead );
00833 if( nrBytesRead + offset > PACKET_SIZE )
00834 {
00835 printf( "Unexpected.\n");
00836 return false;
00837 }
00838 memcpy( buffer+offset, readbuf, nrBytesRead );
00839 nrBytesInBuffer += nrBytesRead;
00840 offset = nrBytesInBuffer;
00841
00842 if( nrBytesInBuffer > 32 )
00843 {
00844 result = NOVATELOEM4_FindNextMessageInBuffer(
00845 buffer,
00846 PACKET_SIZE,
00847 message,
00848 PACKET_SIZE,
00849 &wasEndOfBufferReached,
00850 &wasMessageFound,
00851 &startPosition,
00852 &messageLength,
00853 &messageID,
00854 &nrBadCRC
00855 );
00856 }
00857
00858 if( wasMessageFound && messageID == NOVATELOEM4_BESTPOSB )
00859 {
00860 result = NOVATELOEM4_DecodeBESTPOSB(
00861 message,
00862 messageLength,
00863 &header,
00864 &bestpos
00865 );
00866
00867 if( bestpos.solution_status == NOVATELOEM4_SOLNSTATUS_SOL_COMPUTED )
00868 {
00869 isPositionValid = true;
00870 continue;
00871 }
00872 else
00873 {
00874 offset = 0;
00875 }
00876 }
00877 else
00878 {
00879 offset = 0;
00880
00881 }
00882 }
00883 Sleep(60);
00884 c1 = clock();
00885 elapsed_time_s = ((double)(c1-c0))/((double)CLOCKS_PER_SEC);
00886 }
00887
00888 if( !isPositionValid )
00889 {
00890 printf( "The receiver position is not yet valid. Try again.\n" );
00891 return true;
00892 }
00893 else
00894 {
00895 printf( "A valid receiver position was verified.\n" );
00896 }
00897
00898
00899 sprintf( (char*)message, "unlogall COM%d_ALL\r", SerialPortNumberOnReceiver );
00900 msg = (char*)message;
00901 SendCommand( port, msg );
00902
00903 sprintf( (char*)message, "log com%d TIMEB ontime 5.0\r", SerialPortNumberOnReceiver );
00904 msg = (char*)message;
00905 SendCommand( port, msg );
00906 Sleep(1500);
00907
00908
00909 if( !port.Read( readbuf, PACKET_SIZE, nrBytesRead ) )
00910 {
00911 printf( "port.Read returned false. port %d.\n", SerialPortNumber );
00912 return false;
00913 }
00914 if( !port.Read( readbuf, PACKET_SIZE, nrBytesRead ) )
00915 {
00916 printf( "port.Read returned false. port %d.\n", SerialPortNumber );
00917 return false;
00918 }
00919
00920 coarse_sync_success = false;
00921 time_data.clock_status = NOVATELOEM4_CLOCK_STATUS_UNKNOWN;
00922 c0 = clock();
00923 elapsed_time_s = 0;
00924 while( elapsed_time_s < 30.0 && coarse_sync_success == false )
00925 {
00926 memset( readbuf, 0, PACKET_SIZE );
00927 if( !port.Read( readbuf, PACKET_SIZE, nrBytesRead ) )
00928 {
00929 printf( "port.Read returned false. port %d.\n", SerialPortNumber );
00930 return false;
00931 }
00932
00933 if( nrBytesRead > 0 )
00934 {
00935 printf( "%d bytes read.\n", nrBytesRead );
00936 if( nrBytesRead + offset > PACKET_SIZE )
00937 {
00938 printf( "Unexpected.\n");
00939 return false;
00940 }
00941 memcpy( buffer+offset, readbuf, nrBytesRead );
00942 nrBytesInBuffer += nrBytesRead;
00943 offset = nrBytesInBuffer;
00944
00945 if( nrBytesInBuffer > 32 )
00946 {
00947 result = NOVATELOEM4_FindNextMessageInBuffer(
00948 buffer,
00949 PACKET_SIZE,
00950 message,
00951 PACKET_SIZE,
00952 &wasEndOfBufferReached,
00953 &wasMessageFound,
00954 &startPosition,
00955 &messageLength,
00956 &messageID,
00957 &nrBadCRC
00958 );
00959 }
00960
00961 if( wasMessageFound && messageID == NOVATELOEM4_TIMEB )
00962 {
00963 result = NOVATELOEM4_DecodeTIMEB(
00964 message,
00965 messageLength,
00966 &header,
00967 &time_data
00968 );
00969
00970 if( time_data.clock_status == NOVATELOEM4_CLOCK_STATUS_VALID && time_data.isUTCValid )
00971 {
00972 utc.year = time_data.utc_year;
00973 utc.month = time_data.utc_month;
00974 utc.day = time_data.utc_day;
00975 utc.hour = time_data.utc_hour;
00976 utc.minute = time_data.utc_minute;
00977 utc.seconds = ((float)time_data.utc_milliseconds)/1000.0f;
00978
00979 rs232_transmission_time = messageLength * 9.0 / 115200.0;
00980
00981 utc.seconds -= (float)rs232_transmission_time;
00982
00983 if( utc.seconds < 0 )
00984 {
00985 utc.seconds += 60.0;
00986 if( utc.minute == 0 )
00987 {
00988 utc.minute = 59;
00989 if( utc.hour == 0 )
00990 {
00991 printf( "Too close to midnight to proceed.\n" );
00992 return true;
00993 }
00994 else
00995 {
00996 utc.hour--;
00997 }
00998 }
00999 else
01000 {
01001 utc.minute--;
01002 }
01003 }
01004
01005 result = TIMECONV_SetSystemTime(
01006 utc.year,
01007 utc.month,
01008 utc.day,
01009 utc.hour,
01010 utc.minute,
01011 utc.seconds
01012 );
01013
01014 if( !result )
01015 {
01016 printf("TIMECONV_SetSystemTime returned FALSE.");
01017 return false;
01018 }
01019 else
01020 {
01021 printf( "Coarse synchronization performed using TIMEB message.\n" );
01022 coarse_sync_success = true;
01023 continue;
01024 }
01025 }
01026 else
01027 {
01028 offset = 0;
01029 }
01030 }
01031 else
01032 {
01033 offset = 0;
01034 }
01035 }
01036 Sleep(5);
01037 c1 = clock();
01038 elapsed_time_s = ((double)(c1-c0))/((double)CLOCKS_PER_SEC);
01039 }
01040
01041 if( !coarse_sync_success )
01042 {
01043 printf( "Unable to achieve coarse synchronization. Please try again.\n" );
01044 return false;
01045 }
01046
01047 sprintf( (char*)message, "unlogall COM%d_ALL\r", SerialPortNumberOnReceiver );
01048 msg = (char*)message;
01049 SendCommand( port, msg );
01050
01051
01052 c0 = clock();
01053 elapsed_time_s = 0;
01054 while( elapsed_time_s < 30.0 && pps_sync_success == false )
01055 {
01056 double seconds = 0;
01057 port.WaitOnRingIndicator( 990, ring_detected );
01058 if( ring_detected )
01059 {
01060 result = TIMECONV_GetSystemTime(
01061 &pc_time.utc_year,
01062 &pc_time.utc_month,
01063 &pc_time.utc_day,
01064 &pc_time.utc_hour,
01065 &pc_time.utc_minute,
01066 &pc_time.utc_seconds,
01067 &pc_time.utc_offset,
01068 &pc_time.jd,
01069 &pc_time.gps_week,
01070 &pc_time.gps_tow
01071 );
01072 if( !result )
01073 {
01074 printf( "TIMECONV_GetSystemTime return false." );
01075 return false;
01076 }
01077 seconds = pc_time.utc_seconds;
01078
01079 pc_time.utc_seconds = floor( pc_time.utc_seconds + 1 );
01080 if( pc_time.utc_seconds == 60 )
01081 {
01082 pc_time.utc_seconds = 0;
01083 pc_time.utc_minute++;
01084 if( pc_time.utc_minute == 60 )
01085 {
01086 pc_time.utc_minute = 0;
01087 pc_time.utc_hour++;
01088 if( pc_time.utc_hour == 24 )
01089 {
01090 printf( "Too close to midnight to proceed\n" );
01091 return false;
01092 }
01093 }
01094 }
01095
01096 pulse_count++;
01097 if( pulse_count == 5 )
01098 {
01099 result = TIMECONV_SetSystemTime(
01100 pc_time.utc_year,
01101 pc_time.utc_month,
01102 pc_time.utc_day,
01103 pc_time.utc_hour,
01104 pc_time.utc_minute,
01105 floor(pc_time.utc_seconds)
01106 );
01107 if( !result )
01108 {
01109 printf( "TIMECONV_GetSystemTime return false." );
01110 return false;
01111 }
01112 else
01113 {
01114 pps_sync_success = true;
01115 }
01116 }
01117 else
01118 {
01119 printf( "Pulse detected: Synchronizing in %d s.\n", 5-pulse_count );
01120 }
01121 }
01122 else
01123 {
01124 printf( "%.0fs Remaining. Listening pin 9, ring indicator pin, of COM%d for PPS\n", 30.0 - elapsed_time_s, port.GetPortNumber() );
01125 }
01126 c1 = clock();
01127 elapsed_time_s = ((double)(c1-c0))/((double)CLOCKS_PER_SEC);
01128 }
01129
01130 if( pps_sync_success )
01131 {
01132 printf( "Sync to PPS successful.\n" );
01133 }
01134 else
01135 {
01136 printf( "Failted to sync to PPS. Please try again.\n" );
01137 return true;
01138 }
01139
01140
01141 double mean_diff = 0;
01142 if( PerformPPSTest )
01143 {
01144 int pulsenr = 0;
01145 bool initc2 = true;
01146 clock_t c2;
01147 clock_t c3;
01148 double dt = 0;
01149 double diff = 0;
01150
01151 printf( "Performing PPS test.\n" );
01152
01153
01154 c0 = clock();
01155 elapsed_time_s = 0;
01156 while( elapsed_time_s < 60.0 )
01157 {
01158 port.WaitOnRingIndicator( 1005, ring_detected );
01159 if( ring_detected )
01160 {
01161 if( initc2 )
01162 {
01163 c3 = c2 = clock();
01164 initc2 = false;
01165 }
01166 else
01167 {
01168 c3 = clock();
01169 }
01170 result = TIMECONV_GetSystemTime(
01171 &pc_time.utc_year,
01172 &pc_time.utc_month,
01173 &pc_time.utc_day,
01174 &pc_time.utc_hour,
01175 &pc_time.utc_minute,
01176 &pc_time.utc_seconds,
01177 &pc_time.utc_offset,
01178 &pc_time.jd,
01179 &pc_time.gps_week,
01180 &pc_time.gps_tow
01181 );
01182 if( !result )
01183 {
01184 printf( "TIMECONV_GetSystemTime return false." );
01185 return false;
01186 }
01187 dt = ((double)(c3-c2))/((double)CLOCKS_PER_SEC);
01188 if( pc_time.gps_tow - floor( pc_time.gps_tow ) > 0.5 )
01189 diff = -(floor( pc_time.gps_tow + 0.5 ) - pc_time.gps_tow)*1000.0;
01190 else
01191 diff = (pc_time.gps_tow - floor( pc_time.gps_tow ))*1000.0;
01192
01193 mean_diff += diff;
01194
01195 printf( "Pulse:%2d, dt:%.3f, PC(hh:mm:ss.sss): %02d:%02d:%06.3f difference:%.0f ms\n", pulsenr, dt, pc_time.utc_hour, pc_time.utc_minute, pc_time.utc_seconds, diff );
01196 pulsenr++;
01197 }
01198 else
01199 {
01200 printf( "No ring.\n" );
01201 }
01202 c1 = clock();
01203 elapsed_time_s = ((double)(c1-c0))/((double)CLOCKS_PER_SEC);
01204 }
01205 printf( "Over 60 seconds, the difference in elapsed PC time is %.3f s\n", dt-60.0 );
01206 mean_diff/= (double)pulsenr;
01207 printf( "The mean pulse to pc time difference is: %.3f ms\n", mean_diff );
01208 }
01209
01210
01211 if( AllowTimeForHyperTerminalComparison )
01212 {
01213 sprintf( (char*)message, "log com%d gpzda ontime 1.0\r", SerialPortNumberOnReceiver );
01214 msg = (char*)message;
01215 SendCommand( port, msg );
01216
01217 sprintf( (char*)message, "log com%d bestposa ontime 1.0\r", SerialPortNumberOnReceiver );
01218 msg = (char*)message;
01219 SendCommand( port, msg );
01220 }
01221
01222 port.Close();
01223
01224
01225 if( AllowTimeForHyperTerminalComparison )
01226 {
01227 printf( "The serial port is now closed you may open the port with hyperterminal for comparison.\n" );
01228 if( pps_sync_success )
01229 {
01230 count = 0;
01231 while( count < 40 )
01232 {
01233 TIMECONV_GetSystemTime(
01234 &pc_time.utc_year,
01235 &pc_time.utc_month,
01236 &pc_time.utc_day,
01237 &pc_time.utc_hour,
01238 &pc_time.utc_minute,
01239 &pc_time.utc_seconds,
01240 &pc_time.utc_offset,
01241 &pc_time.jd,
01242 &pc_time.gps_week,
01243 &pc_time.gps_tow
01244 );
01245 if( fabs(pc_time.utc_seconds - floor(pc_time.utc_seconds)) < 0.05 )
01246 {
01247 printf( "%02d:%02d:%.3f\t\t\t %d %.3f\n", pc_time.utc_hour, pc_time.utc_minute, pc_time.utc_seconds, pc_time.gps_week, pc_time.gps_tow );
01248 printf( "\a" );
01249 count++;
01250 Sleep(980);
01251 }
01252 Sleep(2);
01253 }
01254 }
01255 }
01256
01257 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS );
01258 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL );
01259
01260 return true;
01261 }
01262
01263 bool SendCommand( SerialPort& port, std::string msg )
01264 {
01265 unsigned nrBytesRead = 0;
01266 if( !port.Write( (unsigned char*)msg.c_str(), msg.length() ) )
01267 {
01268 printf( "port.Write returned false.\n" );
01269 return false;
01270 }
01271 printf( "Command to COM%d:\n%s\n", port.GetPortNumber(), msg.c_str() );
01272 Sleep(500);
01273 return true;
01274 }