yuma.c

Go to the documentation of this file.
00001 /**
00002 \file    yuma.c
00003 \brief   GNSS core 'c' function library: YUMA format almanacs.
00004 \author  Glenn D. MacGougan (GDM)
00005 \date    2007-11-29
00006 \since   2005-08-14
00007 
00008 \b "LICENSE INFORMATION" \n
00009 Copyright (c) 2007, refer to 'author' doxygen tags \n
00010 All rights reserved. \n
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided the following conditions are met: \n
00014 
00015 - Redistributions of source code must retain the above copyright
00016   notice, this list of conditions and the following disclaimer. \n
00017 - Redistributions in binary form must reproduce the above copyright
00018   notice, this list of conditions and the following disclaimer in the
00019   documentation and/or other materials provided with the distribution. \n
00020 - The name(s) of the contributor(s) may not be used to endorse or promote 
00021   products derived from this software without specific prior written 
00022   permission. \n
00023 
00024 THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 
00025 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
00026 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00028 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
00030 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
00031 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00032 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00033 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
00034 SUCH DAMAGE.
00035 */
00036 
00037 #include <stdio.h>
00038 #include <string.h>
00039 #include "yuma.h"
00040 
00041 #ifndef WIN32
00042 #define _CRT_SECURE_NO_DEPRECATE
00043 #endif
00044 
00045 BOOL YUMA_ReadAlmanacDataFromFile(
00046   const char* yumaFilePath,   //!< path to the input YUMA ASCII file
00047   YUMA_structAlmanac* alm,    //!< pointer to an array of YUMA almanac structs
00048   unsigned char  max_to_read, //!< length of the array
00049   unsigned char* number_read  //!< number of almanac items read
00050   )
00051 {
00052   FILE* in;            // the input file pointer
00053   char buffer[512];    // a buffer big enough to hold one line from the almanac file
00054   char synca, syncb;   // two characters used to sync the file (find the first "ID" string)
00055   int syncFound = 0;   // bool to indicate if "ID" was found in the file
00056   int n;               // counter to indicate the number of items read by sscanf_s
00057   int i;               // counter
00058   unsigned utmp;
00059   
00060   // initialize
00061   *number_read = 0;  
00062 
00063   // check stupid error
00064   if( max_to_read < 1 )
00065     return FALSE;
00066 
00067 #ifndef _CRT_SECURE_NO_DEPRECATE
00068   if( fopen_s( &in, yumaFilePath, "r" ) != 0 )
00069     return FALSE;
00070   if( !in )
00071     return FALSE;
00072 #else
00073   in = fopen( yumaFilePath, "r" );
00074   if( !in )
00075     return FALSE;
00076 #endif
00077 
00078   // sync with the first "ID" found in the file
00079   synca = (char)fgetc(in);  
00080   while( !feof(in) )
00081   {
00082     syncb = (char)fgetc(in);
00083     if( synca == 'I' && syncb == 'D' )
00084     {
00085       syncFound = 1;
00086       break;
00087     }
00088     else
00089     {
00090       synca = syncb;
00091     }
00092   }
00093   if( !syncFound )
00094   {
00095     fclose(in);
00096     return FALSE;
00097   }
00098 
00099   // rewind by two bytes to make things easy below
00100   fseek(in, -2, SEEK_CUR );
00101 
00102   i = 0;
00103   while( !feof(in) && i < max_to_read )
00104   {
00105 #ifndef _CRT_SECURE_NO_DEPRECATE
00106     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "ID:                         %u",  &utmp );              if( n != 1 ){break;} alm[i].prn = (unsigned short)utmp;
00107     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "Health:                     %u",  &utmp );              if( n != 1 ){break;} alm[i].health = (unsigned char)utmp;
00108     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "Eccentricity:               %lf", &(alm[i].ecc) );      if( n != 1 ){break;}
00109     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "Time of Applicability(s):   %lf", &(alm[i].toa) );      if( n != 1 ){break;}
00110     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "Orbital Inclination(rad):   %lf", &(alm[i].i0) );       if( n != 1 ){break;}
00111     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "Rate of Right Ascen(r/s):   %lf", &(alm[i].omegadot) ); if( n != 1 ){break;}
00112     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "SQRT(A)  (m 1/2):           %lf", &(alm[i].sqrta) );    if( n != 1 ){break;}
00113     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "Right Ascen at Week(rad):   %lf", &(alm[i].omega0) );   if( n != 1 ){break;}
00114     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "Argument of Perigee(rad):   %lf", &(alm[i].w) );        if( n != 1 ){break;}
00115     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "Mean Anom(rad):             %lf", &(alm[i].m0) );       if( n != 1 ){break;}
00116     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "Af0(s):                     %lf", &(alm[i].af0) );      if( n != 1 ){break;}
00117     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "Af1(s/s):                   %lf", &(alm[i].af1) );      if( n != 1 ){break;}
00118     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf_s( buffer, "week:                       %u",  &utmp );              if( n != 1 ){break;} alm[i].week = (unsigned short)utmp;
00119 #else
00120     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "ID:                         %u",  &utmp );              if( n != 1 ){break;} alm[i].prn = (unsigned short)utmp;
00121     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "Health:                     %u",  &utmp );              if( n != 1 ){break;} alm[i].health = (unsigned char)utmp;
00122     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "Eccentricity:               %lf", &(alm[i].ecc) );      if( n != 1 ){break;}
00123     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "Time of Applicability(s):   %lf", &(alm[i].toa) );      if( n != 1 ){break;}
00124     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "Orbital Inclination(rad):   %lf", &(alm[i].i0) );       if( n != 1 ){break;}
00125     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "Rate of Right Ascen(r/s):   %lf", &(alm[i].omegadot) ); if( n != 1 ){break;}
00126     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "SQRT(A)  (m 1/2):           %lf", &(alm[i].sqrta) );    if( n != 1 ){break;}
00127     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "Right Ascen at Week(rad):   %lf", &(alm[i].omega0) );   if( n != 1 ){break;}
00128     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "Argument of Perigee(rad):   %lf", &(alm[i].w) );        if( n != 1 ){break;}
00129     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "Mean Anom(rad):             %lf", &(alm[i].m0) );       if( n != 1 ){break;}
00130     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "Af0(s):                     %lf", &(alm[i].af0) );      if( n != 1 ){break;}
00131     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "Af1(s/s):                   %lf", &(alm[i].af1) );      if( n != 1 ){break;}
00132     if( !fgets( buffer, 512, in ) ){break;}  n = sscanf( buffer, "week:                       %u",  &utmp );              if( n != 1 ){break;} alm[i].week = (unsigned short)utmp;
00133 #endif
00134     alm[i].is_af0_af1_high_precision = 0;
00135     alm[i].reserved1 = 0;
00136     i++;
00137 
00138      // sync with the next "ID" found in the file
00139     syncFound = FALSE;
00140     synca = (char)fgetc(in);  
00141     while( !feof(in) )
00142     {
00143       syncb = (char)fgetc(in);
00144       if( synca == 'I' && syncb == 'D' )
00145       {
00146         syncFound = 1;
00147         break;
00148       }
00149       else
00150       {
00151         synca = syncb;
00152       }
00153     }
00154     if( !syncFound )
00155     {
00156       break;
00157     }
00158 
00159     // rewind by two bytes to make things easy below
00160     fseek(in, -2, SEEK_CUR );
00161   }
00162 
00163   *number_read = (unsigned char)i;
00164 
00165   fclose(in);
00166 
00167   return TRUE;
00168 }
00169 
00170 
00171 BOOL YUMA_WriteAlmanacDataToFile(
00172   const char* yumaFilePath,      //!< path to the output YUMA ASCII file
00173   YUMA_structAlmanac* alm,       //!< pointer to an array of YUMA almanac structs
00174   unsigned char number_to_write  //!< length of the array
00175   )
00176 {
00177   char buffer[1024];
00178   unsigned char i;
00179 
00180   FILE* out;
00181 #ifndef _CRT_SECURE_NO_DEPRECATE
00182   if( fopen_s( &out, yumaFilePath, "w") != 0 )
00183     return FALSE;
00184   if( !out )
00185     return FALSE;
00186 #else
00187   out = fopen(yumaFilePath, "w");
00188   if( !out )
00189     return FALSE;
00190 #endif
00191 
00192   for( i = 0; i < number_to_write; i++ )
00193   {
00194     YUMA_WriteSingleAlmanacElementToBuffer( alm[i], buffer, 1024 );
00195     fprintf( out, "%s", buffer );
00196   }
00197 
00198   fclose(out);
00199   return TRUE;
00200 }
00201 
00202   
00203 BOOL YUMA_WriteSingleAlmanacElementToBuffer(
00204   YUMA_structAlmanac alm,   //!< YUMA almanac struct
00205   char* buffer,             //!< buffer to write the YUMA struct information
00206   unsigned short bufferSize //!< size of the buffer, must be greater than 1024 bytes
00207   )
00208 {
00209   int scount = 0;
00210 
00211 #ifndef _CRT_SECURE_NO_DEPRECATE
00212   int dcount = 0;
00213   if( bufferSize < 1024 )
00214   {
00215     sprintf_s( buffer, bufferSize, "" );
00216     return FALSE;
00217   }                                                         
00218   dcount = sprintf_s( buffer+scount, bufferSize-scount, "******** Week %03d almanac for PRN-%02d ********\n", alm.week, alm.prn ); if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00219   dcount = sprintf_s( buffer+scount, bufferSize-scount, "ID:                        % 03d\n",  alm.prn );       if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00220   dcount = sprintf_s( buffer+scount, bufferSize-scount, "Health:                    % 04d\n",  alm.health );    if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00221   dcount = sprintf_s( buffer+scount, bufferSize-scount, "Eccentricity:              % .10g\n", alm.ecc );       if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00222   dcount = sprintf_s( buffer+scount, bufferSize-scount, "Time of Applicability(s):  % .4f\n",  alm.toa );       if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00223   dcount = sprintf_s( buffer+scount, bufferSize-scount, "Orbital Inclination(rad):  % .10g\n", alm.i0 );        if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00224   dcount = sprintf_s( buffer+scount, bufferSize-scount, "Rate of Right Ascen(r/s):  % .10g\n", alm.omegadot );  if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00225   dcount = sprintf_s( buffer+scount, bufferSize-scount, "SQRT(A)  (m 1/2):          % .6f\n",  alm.sqrta );     if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00226   dcount = sprintf_s( buffer+scount, bufferSize-scount, "Right Ascen at Week(rad):  % .10g\n", alm.omega0 );    if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00227   dcount = sprintf_s( buffer+scount, bufferSize-scount, "Argument of Perigee(rad):  % .10g\n", alm.w );         if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00228   dcount = sprintf_s( buffer+scount, bufferSize-scount, "Mean Anom(rad):            % .10g\n", alm.m0 );        if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00229   dcount = sprintf_s( buffer+scount, bufferSize-scount, "Af0(s):                    % .10g\n", alm.af0 );       if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00230   dcount = sprintf_s( buffer+scount, bufferSize-scount, "Af1(s/s):                  % .10g\n", alm.af1 );       if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00231   dcount = sprintf_s( buffer+scount, bufferSize-scount, "week:                      % 03d\n\n",alm.week );      if( dcount < 0 ){ return FALSE; }else{ scount += dcount; }
00232 #else
00233   if( bufferSize < 1024 )
00234   {
00235     sprintf( buffer, "" );
00236     return FALSE;
00237   }
00238   scount += sprintf( buffer+scount, "******** Week %03d almanac for PRN-%02d ********\n", alm.week, alm.prn );
00239   scount += sprintf( buffer+scount, "ID:                         %02d\n",  alm.prn );
00240   scount += sprintf( buffer+scount, "Health:                     %03d\n",  alm.health );
00241   scount += sprintf( buffer+scount, "Eccentricity:               %.10g\n", alm.ecc );
00242   scount += sprintf( buffer+scount, "Time of Applicability(s):   %.4f\n",  alm.toa );
00243   scount += sprintf( buffer+scount, "Orbital Inclination(rad):   %.10g\n", alm.i0 );
00244   scount += sprintf( buffer+scount, "Rate of Right Ascen(r/s):   %.10g\n", alm.omegadot );
00245   scount += sprintf( buffer+scount, "SQRT(A)  (m 1/2):           %.6f\n",  alm.sqrta );
00246   scount += sprintf( buffer+scount, "Right Ascen at Week(rad):   %.10g\n", alm.omega0 );
00247   scount += sprintf( buffer+scount, "Argument of Perigee(rad):   %.10g\n", alm.w );
00248   scount += sprintf( buffer+scount, "Mean Anom(rad):             %.10g\n", alm.m0 );
00249   scount += sprintf( buffer+scount, "Af0(s):                     %.10g\n", alm.af0 );
00250   scount += sprintf( buffer+scount, "Af1(s/s):                   %.10g\n", alm.af1 );
00251   scount += sprintf( buffer+scount, "week:                       %03d\n\n",alm.week );
00252 #endif
00253   return TRUE;
00254 }
00255