Skip to content

Commit

Permalink
Index signal specific data using the signal code
Browse files Browse the repository at this point in the history
Rather than the signal frequency index which is still used in the
observation structure to keep that compact.

When there are many signals the set of signals can change and when the
priorities are recomputed the frequency index can change so the
frequency index is not a reliable key for this state. This is not an
issue with just one signal, or perhaps two, but with more than NFREQ
signals there were subtle issues as the priories changed and the state
was mixed up.

There are a good few structures with just one array of data for each
signal and these have been expanded from being NFREQ+NEXOBS to MAXCODE
so that the signal code can be used as the index. This is a little
wasteful of memory but simple.
  • Loading branch information
ourairquality committed Sep 23, 2024
1 parent 16ea494 commit c34afba
Show file tree
Hide file tree
Showing 12 changed files with 228 additions and 203 deletions.
105 changes: 56 additions & 49 deletions src/convrnx.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ typedef struct { /* stream file type */
raw_t raw; /* input receiver raw data */
rnxctr_t rnx; /* input RINEX control data */
stas_t *stas; /* station list */
uint8_t slips [MAXSAT][NFREQ+NEXOBS]; /* cycle slip flag cache */
halfc_t *halfc[MAXSAT][NFREQ+NEXOBS]; /* half-cycle ambiguity list */
uint8_t slips [MAXSAT][MAXCODE]; /* cycle slip flag cache */
halfc_t *halfc[MAXSAT][MAXCODE]; /* half-cycle ambiguity list */
FILE *fp; /* output file pointer */
} strfile_t;

Expand Down Expand Up @@ -147,7 +147,6 @@ static strfile_t *gen_strfile(int format, const char *opt)
{
strfile_t *str;
gtime_t time0={0};
int i,j;

trace(3,"init_strfile:\n");

Expand Down Expand Up @@ -200,9 +199,10 @@ static strfile_t *gen_strfile(int format, const char *opt)
}

str->stas=NULL;
for (i=0;i<MAXSAT;i++) for (j=0;j<NFREQ+NEXOBS;j++) {
str->slips[i][j]=0;
str->halfc[i][j]=NULL;
for (int i=0;i<MAXSAT;i++)
for (int code=0;code<MAXCODE;code++) {
str->slips[i][code]=0;
str->halfc[i][code]=NULL;
}
str->fp=NULL;
return str;
Expand All @@ -212,7 +212,6 @@ static void free_strfile(strfile_t *str)
{
stas_t *sp,*sp_next;
halfc_t *hp,*hp_next;
int i,j;

trace(3,"free_strfile:\n");

Expand All @@ -229,8 +228,9 @@ static void free_strfile(strfile_t *str)
sp_next=sp->next;
free(sp);
}
for (i=0;i<MAXSAT;i++) for (j=0;j<NFREQ+NEXOBS;j++) {
for (hp=str->halfc[i][j];hp;hp=hp_next) {
for (int i=0;i<MAXSAT;i++)
for (int code=0;code<MAXCODE;code++) {
for (hp=str->halfc[i][code];hp;hp=hp_next) {
hp_next=hp->next;
free(hp);
}
Expand Down Expand Up @@ -618,15 +618,15 @@ static void dump_stas(const strfile_t *str)
#endif
}
/* add half-cycle ambiguity list ---------------------------------------------*/
static int add_halfc(strfile_t *str, int sat, int idx, gtime_t time)
static int add_halfc(strfile_t *str, int sat, int code, gtime_t time)
{
halfc_t *p;

if (!(p=(halfc_t *)calloc(sizeof(halfc_t),1))) return 0;
p->ts=p->te=time;
p->stat=0;
p->next=str->halfc[sat-1][idx];
str->halfc[sat-1][idx]=p;
p->next=str->halfc[sat-1][code];
str->halfc[sat-1][code]=p;
return 1;
}
/* update half-cycle ambiguity -----------------------------------------------*/
Expand All @@ -637,56 +637,59 @@ static void update_halfc(strfile_t *str, obsd_t *obs)
for (i=0;i<NFREQ+NEXOBS;i++) {
if (obs->L[i]==0.0) continue;

int code = obs->code[i];
if (code == CODE_NONE) continue;

/* if no list, start list */
if (!str->halfc[sat-1][i]) {
if (!add_halfc(str,sat,i,obs->time)) continue;
if (!str->halfc[sat-1][code]) {
if (!add_halfc(str,sat,code,obs->time)) continue;
}
/* reset list if true cycle slip */
if ((obs->LLI[i]&LLI_SLIP)&&!(obs->LLI[i]&(LLI_HALFA|LLI_HALFS))) {
str->halfc[sat-1][i]->stat=0;
str->halfc[sat-1][code]->stat=0;
}
if (obs->LLI[i]&LLI_HALFC) { /* halfcyc unresolved */
/* if new list, set unresolved start epoch */
if (str->halfc[sat-1][i]->stat==0) {
str->halfc[sat-1][i]->ts=obs->time;
if (str->halfc[sat-1][code]->stat==0) {
str->halfc[sat-1][code]->ts=obs->time;
}
/* update unresolved end epoch and set status to active */
str->halfc[sat-1][i]->te=obs->time;
str->halfc[sat-1][i]->stat=1;
str->halfc[sat-1][code]->te=obs->time;
str->halfc[sat-1][code]->stat=1;
} /* else if resolved, update status */
else if (str->halfc[sat-1][i]->stat==1) {
else if (str->halfc[sat-1][code]->stat==1) {
if (obs->LLI[i]&LLI_HALFA) {
str->halfc[sat-1][i]->stat=2; /* resolved with add */
str->halfc[sat-1][code]->stat=2; /* resolved with add */
}
else if (obs->LLI[i]&LLI_HALFS) {
str->halfc[sat-1][i]->stat=3; /* resolved with subtract */
str->halfc[sat-1][code]->stat=3; /* resolved with subtract */
}
else {
str->halfc[sat-1][i]->stat=4; /* resolved with no adjust */
str->halfc[sat-1][code]->stat=4; /* resolved with no adjust */
}
/* create new list entry */
if (!add_halfc(str,sat,i,obs->time)) continue;
if (!add_halfc(str,sat,code,obs->time)) continue;
}
}
}
/* dump half-cycle ambiguity list --------------------------------------------*/
static void dump_halfc(const strfile_t *str)
{
#if 0 /* for debug */
halfc_t *p;
char s0[32],s1[32],s2[32],*stats[]={"ADD","SUB","NON"};
int i,j;

#ifdef RTK_DISABLED /* for debug */
trace(2,"# HALF-CYCLE AMBIGUITY CORRECTIONS\n");
trace(2,"# %20s %22s %4s %3s %3s\n","START","END","SAT","FRQ","COR");

for (i=0;i<MAXSAT;i++) for (j=0;j<NFREQ+NEXOBS;j++) {
for (p=str->halfc[i][j];p;p=p->next) {
for (int i=0;i<MAXSAT;i++)
for (int code=0;code<MAXCODE;code++) {
const char *obs=code2obs(code);
for (halfc_t *p=str->halfc[i][code];p;p=p->next) {
if (p->stat<=1) continue;
char s0[8],s1[40],s2[40];
satno2id(i+1,s0);
time2str(p->ts,s1,2);
time2str(p->te,s2,2);
trace(2,"%s %s %4s %3d %3s\n",s1,s2,s0,j+1,stats[p->stat-2]);
const char *stats[]={"ADD","SUB","NON"};
trace(2,"%s %s %4s %2s %3s\n",s1,s2,s0,obs,stats[p->stat-2]);
}
}
#endif
Expand All @@ -695,15 +698,16 @@ static void dump_halfc(const strfile_t *str)
static void resolve_halfc(const strfile_t *str, obsd_t *data, int n)
{
halfc_t *p;
int i,j,sat;
int sat;

for (i=0;i<n;i++) for (j=0;j<NFREQ+NEXOBS;j++) {
for (int i=0;i<n;i++) {
sat=data[i].sat;

for (p=str->halfc[sat-1][j];p;p=p->next) {
if (p->stat<=1) continue; /* unresolved half cycle */
if (timediff(data[i].time,p->ts)<-DTTOL||
timediff(data[i].time,p->te)> DTTOL) continue;
for (int j=0;j<NFREQ+NEXOBS;j++) {
int code = data[i].code[j];
for (p=str->halfc[sat-1][code];p;p=p->next) {
if (p->stat<=1) continue; /* unresolved half cycle */
if (timediff(data[i].time,p->ts)<-DTTOL||
timediff(data[i].time,p->te)> DTTOL) continue;

if (p->stat==2) { /* add half cycle */
data[i].L[j]+=0.5;
Expand All @@ -714,6 +718,7 @@ static void resolve_halfc(const strfile_t *str, obsd_t *data, int n)
data[i].LLI[j]&=~LLI_HALFC;
}
data[i].LLI[j]&=~(LLI_HALFA|LLI_HALFS);
}
}
}
/* scan input files ----------------------------------------------------------*/
Expand Down Expand Up @@ -962,21 +967,23 @@ static void outrnxevent(FILE *fp, const rnxopt_t *opt, gtime_t time, int event,
/* save cycle slips ----------------------------------------------------------*/
static void save_slips(strfile_t *str, obsd_t *data, int n)
{
int i,j;

for (i=0;i<n;i++) for (j=0;j<NFREQ+NEXOBS;j++) {
if (data[i].LLI[j]&LLI_SLIP) str->slips[data[i].sat-1][j]=1;
for (int i=0;i<n;i++)
for (int j=0;j<NFREQ+NEXOBS;j++) {
int sat = data[i].sat;
int code = data[i].code[j];
if (data[i].LLI[j]&LLI_SLIP) str->slips[sat-1][code]=1;
}
}
/* restore cycle slips -------------------------------------------------------*/
static void rest_slips(strfile_t *str, obsd_t *data, int n)
{
int i,j;

for (i=0;i<n;i++) for (j=0;j<NFREQ+NEXOBS;j++) {
if (data[i].L[j]!=0.0&&str->slips[data[i].sat-1][j]) {
data[i].LLI[j]|=LLI_SLIP;
str->slips[data[i].sat-1][j]=0;
for (int i=0;i<n;i++)
for (int j=0;j<NFREQ+NEXOBS;j++) {
int sat = data[i].sat;
int code = data[i].code[j];
if (data[i].L[j]!=0.0&&str->slips[sat-1][code]) {
data[i].LLI[code]|=LLI_SLIP;
str->slips[sat-1][code]=0;
}
}
}
Expand Down
58 changes: 30 additions & 28 deletions src/rcv/novatel.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,18 +408,18 @@ static int decode_rangecmpb(raw_t *raw)
}
lockt=(U4(p+18)&0x1FFFFF)/32.0; /* lock time */

if (raw->tobs[sat-1][idx].time!=0) {
tt=timediff(raw->time,raw->tobs[sat-1][idx]);
lli=(lockt<65535.968&&lockt-raw->lockt[sat-1][idx]+0.05<=tt)?LLI_SLIP:0;
if (raw->tobs[sat-1][code].time!=0) {
tt=timediff(raw->time,raw->tobs[sat-1][code]);
lli=(lockt<65535.968&&lockt-raw->lockt[sat-1][code]+0.05<=tt)?LLI_SLIP:0;
}
else {
lli=0;
}
if (!parity) lli|=LLI_HALFC;
if (halfc ) lli|=LLI_HALFA;
raw->tobs [sat-1][idx]=raw->time;
raw->lockt[sat-1][idx]=lockt;
raw->halfc[sat-1][idx]=halfc;
raw->tobs [sat-1][code]=raw->time;
raw->lockt[sat-1][code]=lockt;
raw->halfc[sat-1][code]=halfc;

snr=((U2(p+20)&0x3FF)>>5)+20.0;
if (!clock) psr=0.0; /* code unlock */
Expand Down Expand Up @@ -492,18 +492,18 @@ static int decode_rangeb(raw_t *raw)
raw->nav.glo_fcn[prn-1]=gfrq; /* fcn+8 */
}
}
if (raw->tobs[sat-1][idx].time!=0) {
tt=timediff(raw->time,raw->tobs[sat-1][idx]);
lli=lockt-raw->lockt[sat-1][idx]+0.05<=tt?LLI_SLIP:0;
if (raw->tobs[sat-1][code].time!=0) {
tt=timediff(raw->time,raw->tobs[sat-1][code]);
lli=lockt-raw->lockt[sat-1][code]+0.05<=tt?LLI_SLIP:0;
}
else {
lli=0;
}
if (!parity) lli|=LLI_HALFC;
if (halfc ) lli|=LLI_HALFA;
raw->tobs [sat-1][idx]=raw->time;
raw->lockt[sat-1][idx]=lockt;
raw->halfc[sat-1][idx]=halfc;
raw->tobs [sat-1][code]=raw->time;
raw->lockt[sat-1][code]=lockt;
raw->halfc[sat-1][code]=halfc;

if (!clock) psr=0.0; /* code unlock */
if (!plock) adr=dop=0.0; /* phase unlock */
Expand Down Expand Up @@ -1087,18 +1087,19 @@ static int decode_rgeb(raw_t *raw)
trace(2,"oem3 regb satellite number error: sys=%d prn=%d\n",sys,prn);
continue;
}
if (raw->tobs[sat-1][freq].time!=0) {
tt=timediff(raw->time,raw->tobs[sat-1][freq]);
lli=lockt-raw->lockt[sat-1][freq]+0.05<tt||
parity!=raw->halfc[sat-1][freq];
int code=freq==0?CODE_L1C:CODE_L2P;
if (raw->tobs[sat-1][code].time!=0) {
tt=timediff(raw->time,raw->tobs[sat-1][code]);
lli=lockt-raw->lockt[sat-1][code]+0.05<tt||
parity!=raw->halfc[sat-1][code];
}
else {
lli=0;
}
if (!parity) lli|=2;
raw->tobs [sat-1][freq]=raw->time;
raw->lockt[sat-1][freq]=lockt;
raw->halfc[sat-1][freq]=parity;
raw->tobs [sat-1][code]=raw->time;
raw->lockt[sat-1][code]=lockt;
raw->halfc[sat-1][code]=parity;

if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) {
raw->obs.n=0;
Expand All @@ -1110,7 +1111,7 @@ static int decode_rgeb(raw_t *raw)
raw->obs.data[index].SNR[freq]=
0.0<=snr&&snr<255.0?(uint16_t)(snr/SNR_UNIT+0.5):0;
raw->obs.data[index].LLI[freq]=(uint8_t)lli;
raw->obs.data[index].code[freq]=freq==0?CODE_L1C:CODE_L2P;
raw->obs.data[index].code[freq]=code;
}
}
return 1;
Expand Down Expand Up @@ -1153,18 +1154,19 @@ static int decode_rged(raw_t *raw)
adr_rolls=floor((psr/(freq==0?WL1:WL2)-adr)/MAXVAL+0.5);
adr=adr+MAXVAL*adr_rolls;

if (raw->tobs[sat-1][freq].time!=0) {
tt=timediff(raw->time,raw->tobs[sat-1][freq]);
lli=lockt-raw->lockt[sat-1][freq]+0.05<tt||
parity!=raw->halfc[sat-1][freq];
int code = freq==0?CODE_L1C:CODE_L2P;
if (raw->tobs[sat-1][code].time!=0) {
tt=timediff(raw->time,raw->tobs[sat-1][code]);
lli=lockt-raw->lockt[sat-1][code]+0.05<tt||
parity!=raw->halfc[sat-1][code];
}
else {
lli=0;
}
if (!parity) lli|=2;
raw->tobs [sat-1][freq]=raw->time;
raw->lockt[sat-1][freq]=lockt;
raw->halfc[sat-1][freq]=parity;
raw->tobs [sat-1][code]=raw->time;
raw->lockt[sat-1][code]=lockt;
raw->halfc[sat-1][code]=parity;

if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) {
raw->obs.n=0;
Expand All @@ -1175,7 +1177,7 @@ static int decode_rged(raw_t *raw)
raw->obs.data[index].D [freq]=(float)dop;
raw->obs.data[index].SNR[freq]=(uint16_t)(snr/SNR_UNIT+0.5);
raw->obs.data[index].LLI[freq]=(uint8_t)lli;
raw->obs.data[index].code[freq]=freq==0?CODE_L1C:CODE_L2P;
raw->obs.data[index].code[freq]=code;
}
}
return 1;
Expand Down
Loading

0 comments on commit c34afba

Please sign in to comment.