Changeset 270 in ntrip


Ignore:
Timestamp:
Nov 3, 2006, 12:50:11 PM (17 years ago)
Author:
stoecker
Message:

added GLONASS

Location:
trunk/rtcm3torinex
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/rtcm3torinex/rtcm3torinex.c

    r269 r270  
    11/*
    22  Converter for RTCM3 data to RINEX.
    3   $Id: rtcm3torinex.c,v 1.6 2006/11/02 13:34:00 stoecker Exp $
     3  $Id: rtcm3torinex.c,v 1.7 2006/11/02 13:54:43 stoecker Exp $
    44  Copyright (C) 2005-2006 by Dirk Stoecker <stoecker@euronik.eu>
    55
     
    5050
    5151/* CVS revision and version */
    52 static char revisionstr[] = "$Revision: 1.6 $";
     52static char revisionstr[] = "$Revision: 1.7 $";
    5353
    5454static uint32_t CRC24(long size, const unsigned char *buf)
     
    145145#define SKIPBITS(b) { LOADBITS(b) numbits -= (b); }
    146146
     147struct leapseconds { /* specify the day of leap second */
     148  int day;        /* this is the day, where 23:59:59 exists 2 times */
     149  int month;      /* not the next day! */
     150  int year;
     151  int taicount;
     152};
     153static const int months[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
     154static const struct leapseconds leap[] = {
     155/*{31, 12, 1971, 11},*/
     156/*{31, 12, 1972, 12},*/
     157/*{31, 12, 1973, 13},*/
     158/*{31, 12, 1974, 14},*/
     159/*{31, 12, 1975, 15},*/
     160/*{31, 12, 1976, 16},*/
     161/*{31, 12, 1977, 17},*/
     162/*{31, 12, 1978, 18},*/
     163/*{31, 12, 1979, 19},*/
     164{30, 06, 1981,20},
     165{30, 06, 1982,21},
     166{30, 06, 1983,22},
     167{30, 06, 1985,23},
     168{31, 12, 1987,24},
     169{31, 12, 1989,25},
     170{31, 12, 1990,26},
     171{30, 06, 1992,27},
     172{30, 06, 1993,28},
     173{30, 06, 1994,29},
     174{31, 12, 1995,30},
     175{30, 06, 1997,31},
     176{31, 12, 1998,32},
     177{31, 12, 2005,33},
     178{0,0,0,0} /* end marker */
     179};
     180#define GPSLEAPSTART    19 /* 19 leap seconds existed at 6.1.1980 */
     181
     182static int longyear(int year, int month)
     183{
     184  if(!(year % 4) && (!(year % 400) || (year % 100)))
     185  {
     186    if(!month || month == 2)
     187      return 1;
     188  }
     189  return 0;
     190}
     191
     192static int gnumleap(int year, int month, int day)
     193{
     194  int ls = 0;
     195  const struct leapseconds *l;
     196
     197  for(l = leap; l->taicount && year >= l->year; ++l)
     198  {
     199    if(year > l->year || month > l->month || day > l->day)
     200       ls = l->taicount - GPSLEAPSTART;
     201  }
     202  return ls;
     203}
     204
     205static void updatetime(int *week, int *tow, int tk)
     206{
     207  int y,m,d,k,l;
     208  unsigned int j = *week*(7*24*60*60) + *tow + 5*24*60*60+3*60*60;
     209  int glo_daynumber = 0, glo_timeofday;
     210  for(y = 1980; j >= (unsigned int)(k = (l = (365+longyear(y,0)))*24*60*60)
     211  + gnumleap(y+1,1,1); ++y)
     212  {
     213    j -= k; glo_daynumber += l;
     214  }
     215  for(m = 1; j >= (unsigned int)(k = (l = months[m]+longyear(y, m))*24*60*60)
     216  + gnumleap(y, m+1, 1); ++m)
     217  {
     218    j -= k; glo_daynumber += l;
     219  }
     220  for(d = 1; j >= 24UL*60UL*60UL + gnumleap(y, m, d+1); ++d)
     221    j -= 24*60*60;
     222  glo_daynumber -= 16*365+4-d;
     223  glo_timeofday = j-gnumleap(y, m, d);
     224
     225  if(tk < 5*60*1000 && glo_timeofday > 23*60*60)
     226    *tow += 24*60*60;
     227  else if(glo_timeofday < 5*60 && tk > 23*60*60*1000)
     228    *tow -= 24*60*60;
     229  *tow += tk/1000-glo_timeofday;
     230  if(*tow < 0) {*tow += 24*60*60*7; --*week; }
     231  if(*tow >= 24*60*60*7) {*tow -= 24*60*60*7; ++*week; }
     232}
     233
    147234int RTCM3Parser(struct RTCM3ParserData *handle)
    148235{
     
    155242    uint64_t numbits = 0, bitfield = 0;
    156243    int size = handle->size, type;
     244    int syncf, old = 0;
    157245    unsigned char *data = handle->Message+3;
    158246
     
    171259          lastlockl1[i] = lastlockl2[i] = 0;
    172260
    173         gnss = &handle->Data;
    174         memset(gnss, 0, sizeof(*gnss));
     261        gnss = &handle->DataNew;
    175262
    176263        SKIPBITS(12) /* id */
     
    179266          ++handle->GPSWeek;
    180267        handle->GPSTOW = i/1000;
     268        if(gnss->week && (gnss->timeofweek != i || gnss->week
     269        != handle->GPSWeek))
     270        {
     271          handle->Data = *gnss;
     272          memset(gnss, 0, sizeof(*gnss));
     273          old = 1;
     274        }
    181275        gnss->timeofweek = i;
    182276        gnss->week = handle->GPSWeek;
    183277
    184         SKIPBITS(1) /* sync */
     278        GETBITS(syncf,1) /* sync */
    185279        GETBITS(i,5)
    186280        gnss->numsats = i;
     
    299393          handle->lastlockl2[i] = lastlockl2[i];
    300394        }
    301         if(wasamb) /* not RINEX compatible without */
    302           ret = 1;
    303         else
    304           ret = 2;
     395        if(!syncf && !old)
     396        {
     397          handle->Data = *gnss;
     398          memset(gnss, 0, sizeof(*gnss));
     399        }
     400        if(!syncf || old)
     401        {
     402          if(wasamb) /* not RINEX compatible without */
     403            ret = 1;
     404          else
     405            ret = 2;
     406        }
    305407      }
    306408      break;
     409    case 1009: case 1010: case 1011: case 1012:
     410      {
     411        int lastlockl1[64];
     412        int lastlockl2[64];
     413        struct gnssdata *gnss;
     414        int i, num;
     415        int wasamb=0;
     416
     417        for(i = 0; i < 64; ++i)
     418          lastlockl1[i] = lastlockl2[i] = 0;
     419
     420        gnss = &handle->DataNew;
     421
     422        SKIPBITS(12) /* id */;
     423        GETBITS(i,27) /* tk */
     424
     425        updatetime(&handle->GPSWeek, &handle->GPSTOW, i);
     426        i = handle->GPSTOW*1000;
     427        if(gnss->week && (gnss->timeofweek != i || gnss->week
     428        != handle->GPSWeek))
     429        {
     430          handle->Data = *gnss;
     431          memset(gnss, 0, sizeof(*gnss));
     432          old = 1;
     433        }
     434
     435        gnss->timeofweek = i;
     436        gnss->week = handle->GPSWeek;
     437
     438        GETBITS(syncf,1) /* sync */
     439        GETBITS(i,5)
     440        gnss->numsats += i;
     441
     442        SKIPBITS(4) /* smind, smint */
     443
     444        for(num = gnss->numsats-i; num < gnss->numsats; ++num)
     445        {
     446          int sv, code, l1range, c,l,s,ce,le,se,amb=0;
     447
     448          GETBITS(sv, 6)
     449          if(!sv || sv > 24)
     450          {
     451            --num; --gnss->numsats;
     452          }
     453          else
     454          {
     455            int freq;
     456            gnss->satellites[num] = sv-1 + PRN_GLONASS_START;
     457            /* L1 */
     458            GETBITS(code, 1)
     459            GETBITS(freq, 5)
     460            if(code)
     461            {
     462              c = GNSSDF_P1DATA;  ce = GNSSENTRY_P1DATA;
     463              l = GNSSDF_L1PDATA; le = GNSSENTRY_L1PDATA;
     464              s = GNSSDF_S1PDATA; se = GNSSENTRY_S1PDATA;
     465            }
     466            else
     467            {
     468              c = GNSSDF_C1DATA;  ce = GNSSENTRY_C1DATA;
     469              l = GNSSDF_L1CDATA; le = GNSSENTRY_L1CDATA;
     470              s = GNSSDF_S1CDATA; se = GNSSENTRY_S1CDATA;
     471            }
     472            GETBITS(l1range, 25)
     473            if(l1range != 0x80000)
     474            {
     475              gnss->dataflags[num] |= c;
     476              gnss->measdata[num][ce] = l1range*0.02;
     477            }
     478            GETBITSSIGN(i, 20)
     479            if(i != 0x80000)
     480            {
     481              gnss->dataflags[num] |= l;
     482              gnss->measdata[num][le] = l1range*0.02+i*0.0005;
     483            }
     484            GETBITS(i, 7)
     485            lastlockl1[sv] = i;
     486            if(handle->lastlockl1[sv] > i)
     487              gnss->dataflags[num] |= GNSSDF_LOCKLOSSL1;
     488            if(type == 1010 || type == 1012)
     489            {
     490              GETBITS(amb,7)
     491              if(amb && (gnss->dataflags[num] & c))
     492              {
     493                gnss->measdata[num][ce] += amb*599584.916;
     494                gnss->measdata[num][le] += amb*599584.916;
     495                ++wasamb;
     496              }
     497              GETBITS(i, 8)
     498              if(i)
     499              {
     500                gnss->dataflags[num] |= s;
     501                gnss->measdata[num][se] = i*0.25;
     502                i /= 4*4;
     503                if(i > 9) i = 9;
     504                else if(i < 1) i = 1;
     505                gnss->snrL1[num] = i;
     506              }
     507            }
     508            gnss->measdata[num][le] /= GLO_WAVELENGTH_L1(freq-7);
     509            if(type == 1011 || type == 1012)
     510            {
     511              /* L2 */
     512              GETBITS(code,2)
     513              if(code)
     514              {
     515                c = GNSSDF_P2DATA;  ce = GNSSENTRY_P2DATA;
     516                l = GNSSDF_L2PDATA; le = GNSSENTRY_L2PDATA;
     517                s = GNSSDF_S2PDATA; se = GNSSENTRY_S2PDATA;
     518              }
     519              else
     520              {
     521                c = GNSSDF_C2DATA;  ce = GNSSENTRY_C2DATA;
     522                l = GNSSDF_L2CDATA; le = GNSSENTRY_L2CDATA;
     523                s = GNSSDF_S2CDATA; se = GNSSENTRY_S2CDATA;
     524              }
     525              GETBITSSIGN(i,14)
     526              if(i != 0x2000)
     527              {
     528                gnss->dataflags[num] |= c;
     529                gnss->measdata[num][ce] = l1range*0.02+i*0.02
     530                +amb*599584.916;
     531              }
     532              GETBITSSIGN(i,20)
     533              if(i != 0x80000)
     534              {
     535                gnss->dataflags[num] |= l;
     536                gnss->measdata[num][le] = l1range*0.02+i*0.0005
     537                +amb*599584.915;
     538              }
     539              GETBITS(i,7)
     540              lastlockl2[sv] = i;
     541              if(handle->lastlockl2[sv] > i)
     542                gnss->dataflags[num] |= GNSSDF_LOCKLOSSL2;
     543              if(type == 1012)
     544              {
     545                GETBITS(i, 8)
     546                if(i)
     547                {
     548                  gnss->dataflags[num] |= s;
     549                  gnss->measdata[num][se] = i*0.25;
     550                  i /= 4*4;
     551                  if(i > 9) i = 9;
     552                  else if(i < 1) i = 1;
     553                  gnss->snrL2[num] = i;
     554                }
     555              }
     556              gnss->measdata[num][le] /= GLO_WAVELENGTH_L2(freq-7);
     557            }
     558          }
     559        }
     560        for(i = 0; i < 64; ++i)
     561        {
     562          handle->lastlockl1[i] = lastlockl1[i];
     563          handle->lastlockl2[i] = lastlockl2[i];
     564        }
     565        if(!syncf && !old)
     566        {
     567          handle->Data = *gnss;
     568          memset(gnss, 0, sizeof(*gnss));
     569        }
     570        if(!syncf || old)
     571        {
     572          if(wasamb) /* not RINEX compatible without */
     573            ret = 1;
     574          else
     575            ret = 2;
     576        }
     577      }
     578      break;
    307579    }
    308580  }
     
    310582}
    311583
    312 static int longyear(int year, int month)
    313 {
    314   if(!(year % 4) && (!(year % 400) || (year % 100)))
    315   {
    316     if(!month || month == 2)
    317       return 1;
    318   }
    319   return 0;
    320 }
    321 
    322 void converttime(struct converttimeinfo *c, int week, int tow)
    323 {
    324   /* static variables */
    325   static const int months[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    326 
     584struct Header
     585{
     586  const char *version;
     587  const char *pgm;
     588  const char *marker;
     589  const char *observer;
     590  const char *receiver;
     591  const char *antenna;
     592  const char *position;
     593  const char *antennaposition;
     594  const char *wavelength;
     595  const char *typesofobs; /* should not be modified outside */
     596  const char *timeoffirstobs; /* should not be modified outside */
     597};
     598
     599#define MAXHEADERLINES 50
     600#define MAXHEADERBUFFERSIZE 4096
     601struct HeaderData
     602{
     603  union
     604  {
     605    struct Header named;
     606    const char *unnamed[MAXHEADERLINES];
     607  } data;
     608  int  numheaders;
     609};
     610
     611struct converttimeinfo {
     612  int second;    /* seconds of GPS time [0..59] */
     613  int minute;    /* minutes of GPS time [0..59] */
     614  int hour;      /* hour of GPS time [0..24] */
     615  int day;       /* day of GPS time [1..28..30(31)*/
     616  int month;     /* month of GPS time [1..12]*/
     617  int year;      /* year of GPS time [1980..] */
     618};
     619
     620static void converttime(struct converttimeinfo *c, int week, int tow)
     621{
    327622  int i, k, doy, j; /* temporary variables */
    328623  j = week*(7*24*60*60) + tow + 5*24*60*60;
     
    342637  c->day = doy - j;
    343638}
    344 
    345 struct Header
    346 {
    347   const char *version;
    348   const char *pgm;
    349   const char *marker;
    350   const char *observer;
    351   const char *receiver;
    352   const char *antenna;
    353   const char *position;
    354   const char *antennaposition;
    355   const char *wavelength;
    356   const char *typesofobs; /* should not be modified outside */
    357   const char *timeoffirstobs; /* should not be modified outside */
    358 };
    359 
    360 #define MAXHEADERLINES 50
    361 #define MAXHEADERBUFFERSIZE 4096
    362 struct HeaderData
    363 {
    364   union
    365   {
    366     struct Header named;
    367     const char *unnamed[MAXHEADERLINES];
    368   } data;
    369   int  numheaders;
    370 };
    371639
    372640void HandleHeader(struct RTCM3ParserData *Parser)
     
    647915          && Parser->Data.satellites[i] <= PRN_GLONASS_END)
    648916            printf("R%02d", Parser->Data.satellites[i] - (PRN_GLONASS_START-1));
     917          else if(Parser->Data.satellites[i] >= PRN_WAAS_START
     918          && Parser->Data.satellites[i] <= PRN_WAAS_END)
     919            printf("S%02d", Parser->Data.satellites[i] - PRN_WAAS_START);
    649920          else
    650921            printf("%3d", Parser->Data.satellites[i]);
     
    692963
    693964#ifndef NO_RTCM3_MAIN
    694 static char datestr[]     = "$Date: 2006/11/02 13:34:00 $";
     965static char datestr[]     = "$Date: 2006/11/02 13:54:43 $";
    695966
    696967/* The string, which is send as agent in HTTP request */
     
    7751046{0,0,0,0}};
    7761047#endif
    777 #define ARGOPT "d:hp:r:s:u:f:"
     1048#define ARGOPT "-d:hp:r:s:u:f:"
     1049
     1050static const char *geturl(const char *url, struct Args *args)
     1051{
     1052  static char buf[1000];
     1053  static char *Buffer = buf;
     1054  static char *Bufend = buf+sizeof(buf);
     1055
     1056  if(strncmp("ntrip:", url, 6))
     1057    return "URL must start with 'ntrip:'.";
     1058  url += 6; /* skip ntrip: */
     1059
     1060  if(*url != '@' && *url != '/')
     1061  {
     1062    /* scan for mountpoint */
     1063    args->data = Buffer;
     1064    while(*url && *url != '@' && *url != '/' && Buffer != Bufend)
     1065      *(Buffer++) = *(url++);
     1066    if(Buffer == args->data)
     1067      return "Mountpoint required.";
     1068    else if(Buffer >= Bufend-1)
     1069      return "Parsing buffer too short.";
     1070    *(Buffer++) = 0;
     1071  }
     1072
     1073  if(*url == '/') /* username and password */
     1074  {
     1075    ++url;
     1076    args->user = Buffer;
     1077    while(*url && *url != '@' && *url != ':' && Buffer != Bufend)
     1078      *(Buffer++) = *(url++);
     1079    if(Buffer == args->user)
     1080      return "Username cannot be empty.";
     1081    else if(Buffer >= Bufend-1)
     1082      return "Parsing buffer too short.";
     1083    *(Buffer++) = 0;
     1084
     1085    if(*url == ':') ++url;
     1086
     1087    args->password = Buffer;
     1088    while(*url && *url != '@' && Buffer != Bufend)
     1089      *(Buffer++) = *(url++);
     1090    if(Buffer == args->password)
     1091      return "Password cannot be empty.";
     1092    else if(Buffer >= Bufend-1)
     1093      return "Parsing buffer too short.";
     1094    *(Buffer++) = 0;
     1095  }
     1096
     1097  if(*url == '@') /* server */
     1098  {
     1099    ++url;
     1100    args->server = Buffer;
     1101    while(*url && *url != ':' && Buffer != Bufend)
     1102      *(Buffer++) = *(url++);
     1103    if(Buffer == args->server)
     1104      return "Servername cannot be empty.";
     1105    else if(Buffer >= Bufend-1)
     1106      return "Parsing buffer too short.";
     1107    *(Buffer++) = 0;
     1108
     1109    if(*url == ':')
     1110    {
     1111      char *s2 = 0;
     1112      args->port = strtol(++url, &s2, 10);
     1113      if(*s2 || args->port <= 0 || args->port > 0xFFFF)
     1114        return "Illegal port number.";
     1115      url = s2;
     1116    }
     1117  }
     1118
     1119  return *url ? "Garbage at end of server string." : 0;
     1120}
    7781121
    7791122static int getargs(int argc, char **argv, struct Args *args)
     
    8111154        res = 0;
    8121155      break;
     1156    case 1:
     1157      {
     1158        const char *err;
     1159        if((err = geturl(optarg, args)))
     1160        {
     1161          fprintf(stderr, "%s\n\n", err);
     1162          res = 0;
     1163        }
     1164      }
     1165      break;
    8131166    case -1: break;
    8141167    }
     
    8351188    " -r " LONG_OPT("--port       ") "the server port number (default 80)\n"
    8361189    " -u " LONG_OPT("--user       ") "the user name\n"
    837     , revisionstr, datestr, argv[0]);
     1190    "or using an URL:\n%s ntrip:mountpoint[/username[:password]][@server[:port]]\n"
     1191    , revisionstr, datestr, argv[0], argv[0]);
    8381192    exit(1);
    8391193  }
  • trunk/rtcm3torinex/rtcm3torinex.h

    r268 r270  
    44/*
    55  Converter for RTCM3 data to RINEX.
    6   $Id: rtcm3torinex.c,v 1.5 2006/08/29 15:42:36 stoecker Exp $
     6  $Id: rtcm3torinex.h,v 1.1 2006/11/02 13:34:00 stoecker Exp $
    77  Copyright (C) 2005-2006 by Dirk Stoecker <stoecker@euronik.eu>
    88
     
    2727#define PRN_GLONASS_START         38
    2828#define PRN_GLONASS_END           61
     29#define PRN_WAAS_START            120
     30#define PRN_WAAS_END              138
    2931
    3032#define GNSSENTRY_C1DATA     0
     
    7779#define RINEXENTRY_NUMBER     10
    7880
    79 #define LIGHTSPEED         2.99792458e8    /* m/sec                                           */
     81#define LIGHTSPEED         2.99792458e8    /* m/sec */
    8082#define GPS_FREQU_L1       1575420000.0  /* Hz */
    8183#define GPS_FREQU_L2       1227600000.0  /* Hz */
    8284#define GPS_WAVELENGTH_L1  (LIGHTSPEED / GPS_FREQU_L1) /* m */
    8385#define GPS_WAVELENGTH_L2  (LIGHTSPEED / GPS_FREQU_L2) /* m */
     86
     87#define GLO_FREQU_L1_BASE  1602000000.0  /* Hz */
     88#define GLO_FREQU_L2_BASE  1246000000.0  /* Hz */
     89#define GLO_FREQU_L1_STEP      562500.0  /* Hz */
     90#define GLO_FREQU_L2_STEP      437500.0  /* Hz */
     91#define GLO_FREQU_L1(a)      (GLO_FREQU_L1_BASE+(a)*GLO_FREQU_L1_STEP)
     92#define GLO_FREQU_L2(a)      (GLO_FREQU_L2_BASE+(a)*GLO_FREQU_L2_STEP)
     93#define GLO_WAVELENGTH_L1(a) (LIGHTSPEED / GLO_FREQU_L1(a)) /* m */
     94#define GLO_WAVELENGTH_L2(a) (LIGHTSPEED / GLO_FREQU_L2(a)) /* m */
    8495
    8596/* unimportant, only for approx. time needed */
     
    110121  int    GPSTOW;        /* in seconds */
    111122  struct gnssdata Data;
     123  struct gnssdata DataNew;
    112124  int    size;
    113125  int    lastlockl1[64];
     
    121133};
    122134
    123 struct converttimeinfo {
    124   int second;    /* seconds of GPS time [0..59] */
    125   int minute;    /* minutes of GPS time [0..59] */
    126   int hour;      /* hour of GPS time [0..24] */
    127   int day;       /* day of GPS time [1..28..30(31)*/
    128   int month;     /* month of GPS time [1..12]*/
    129   int year;      /* year of GPS time [1980..] */
    130 };
    131 
    132135void HandleHeader(struct RTCM3ParserData *Parser);
    133136int RTCM3Parser(struct RTCM3ParserData *handle);
    134137void HandleByte(struct RTCM3ParserData *Parser, unsigned int byte);
    135 void converttime(struct converttimeinfo *c, int week, int tow);
    136138
    137139#endif /* RTCM3TORINEX_H */
Note: See TracChangeset for help on using the changeset viewer.