MADOCALIB version 1.4
Introduction
MADOCALIB (MADOCA-PPP test library) version 1.4 has been released. It is a software that handles MADOCA-PPP (muti-GNSS advanced orbit and clock augmentation) messages, one of the high-precision positioning messages from the Quasi-Zenith Satellite, Michibiki. Version 1.2 was reported in article,High-Precision GPS Positioning with MADOCALIB. This new version has been improved to handle phase information and multiple wide-area ionospheric information.
In addition, this new version 1.4 includes sample files for precise point positioning (PPP), PPP-AR, which adds ambiguity resolution (AR) to PPP in relation to the code and phase, and a batch file that handles the wide-area ionospheric information that will be broadcast from the upcoming Michibiki 6 and 7 satellites.
This MADOCALIB is an application for Windows. Here, I will build MADOCALIB version 1.4 on a Mac and run this sample. I think this method can also be applied to Linux PC and Raspberry Pi.
Building rnx2rtkp
First, build the post-processing program rnx2rtkp
. Download MADOCALIB using git
or similar (git clone https://github.com/QZSS-Strategy-Office/madocalib
) and create the following file by modifying the existing makefile
. For lines that start with a space, all of those spaces are tab characters. The path has been modified and the Windows-related defines have been deleted.
app/consapp/rnx2rtkp/gcc_mingw/makefile.linux
# makefile for MADOCALIB rnx2rtkp.exe
# Rev.2024/07/01
BINDIR = ../../../../bin
SRC = ../../../../src
CC = gcc
OPTS = -DTRACE -DENAGLO -DENAQZS -DENAGAL -DENACMP -DENAIRN -DNFREQ=5 -DNEXOBS=5
CFLAGS = -Wall -O3 -ansi -pedantic -Wno-unused-but-set-variable -I$(SRC) $(OPTS) -g
LDLIBS =
OBJS = rnx2rtkp.o rtkcmn.o rinex.o rtkpos.o postpos.o solution.o lambda.o geoid.o sbas.o preceph.o pntpos.o ephemeris.o options.o ppp.o ppp_ar.o ppp_iono.o rtcm.o rtcm2.o rtcm3.o rtcm3e.o ionex.o tides.o mdccssr.o mdciono.o
rnx2rtkp : $(OBJS)
$(CC) -o rnx2rtkp $(OBJS) $(LDLIBS)
rnx2rtkp.o : ../rnx2rtkp.c
$(CC) -c $(CFLAGS) ../rnx2rtkp.c
rtkcmn.o : $(SRC)/rtkcmn.c
$(CC) -c $(CFLAGS) $(SRC)/rtkcmn.c
rinex.o : $(SRC)/rinex.c
$(CC) -c $(CFLAGS) $(SRC)/rinex.c
rtkpos.o : $(SRC)/rtkpos.c
$(CC) -c $(CFLAGS) $(SRC)/rtkpos.c
postpos.o : $(SRC)/postpos.c
$(CC) -c $(CFLAGS) $(SRC)/postpos.c
solution.o : $(SRC)/solution.c
$(CC) -c $(CFLAGS) $(SRC)/solution.c
lambda.o : $(SRC)/lambda.c
$(CC) -c $(CFLAGS) $(SRC)/lambda.c
geoid.o : $(SRC)/geoid.c
$(CC) -c $(CFLAGS) $(SRC)/geoid.c
sbas.o : $(SRC)/sbas.c
$(CC) -c $(CFLAGS) $(SRC)/sbas.c
preceph.o : $(SRC)/preceph.c
$(CC) -c $(CFLAGS) $(SRC)/preceph.c
pntpos.o : $(SRC)/pntpos.c
$(CC) -c $(CFLAGS) $(SRC)/pntpos.c
ephemeris.o: $(SRC)/ephemeris.c
$(CC) -c $(CFLAGS) $(SRC)/ephemeris.c
options.o : $(SRC)/options.c
$(CC) -c $(CFLAGS) $(SRC)/options.c
ppp.o : $(SRC)/ppp.c
$(CC) -c $(CFLAGS) $(SRC)/ppp.c
ppp_ar.o : $(SRC)/ppp_ar.c
$(CC) -c $(CFLAGS) $(SRC)/ppp_ar.c
ppp_iono.o : $(SRC)/ppp_iono.c
$(CC) -c $(CFLAGS) $(SRC)/ppp_iono.c
rtcm.o : $(SRC)/rtcm.c
$(CC) -c $(CFLAGS) $(SRC)/rtcm.c
rtcm2.o : $(SRC)/rtcm2.c
$(CC) -c $(CFLAGS) $(SRC)/rtcm2.c
rtcm3.o : $(SRC)/rtcm3.c
$(CC) -c $(CFLAGS) $(SRC)/rtcm3.c
rtcm3e.o : $(SRC)/rtcm3e.c
$(CC) -c $(CFLAGS) $(SRC)/rtcm3e.c
ionex.o : $(SRC)/ionex.c
$(CC) -c $(CFLAGS) $(SRC)/ionex.c
tides.o : $(SRC)/tides.c
$(CC) -c $(CFLAGS) $(SRC)/tides.c
mdccssr.o : $(SRC)/mdccssr.c
$(CC) -c $(CFLAGS) $(SRC)/mdccssr.c
mdciono.o : $(SRC)/mdciono.c
$(CC) -c $(CFLAGS) $(SRC)/mdciono.c
rnx2rtkp.o : $(SRC)/rtklib.h
rtkcmn.o : $(SRC)/rtklib.h
rinex.o : $(SRC)/rtklib.h
rtkpos.o : $(SRC)/rtklib.h
postpos.o : $(SRC)/rtklib.h
solution.o : $(SRC)/rtklib.h
lambda.o : $(SRC)/rtklib.h
geoid.o : $(SRC)/rtklib.h
sbas.o : $(SRC)/rtklib.h
preceph.o : $(SRC)/rtklib.h
pntpos.o : $(SRC)/rtklib.h
ephemeris.o: $(SRC)/rtklib.h
options.o : $(SRC)/rtklib.h
ppp.o : $(SRC)/rtklib.h
ppp_ar.o : $(SRC)/rtklib.h
ppp_iono.o : $(SRC)/rtklib.h
rtcm.o : $(SRC)/rtklib.h
rtcm2.o : $(SRC)/rtklib.h
rtcm3.o : $(SRC)/rtklib.h
rtcm3e.o : $(SRC)/rtklib.h
ionex.o : $(SRC)/rtklib.h
tides.o : $(SRC)/rtklib.h
mdccssr.o : $(SRC)/rtklib.h
mdciono.o : $(SRC)/rtklib.h
install :
cp rnx2rtkp $(BINDIR)
clean :
rm *.o
rm rnx2rtkp
To actually build, pass this file as an argument to the make
command. This will generate rnx2rtkp
in the bin
directory.
make -f makefile.linux
make -f makefile.linux install
Building cssr2ssr
Next, build the program cssr2ssr
that converts the MADOCA-PPP message format CSSR (compact state space representation) to the widely used RTCM (Radio Technical Commission for Maritime Services) SSR (state space representation) format. As with rnx2rtkp
, copy the existing makefile
and modify it as follows:
app/consapp/cssr2ssr/gcc_mingw/makefile.linux
# makefile for MADOCALIB cssr2ssr.exe
# Rev.2024/09/03
BINDIR = ../../../../bin
SRC = ../../../../src
CC = gcc
OPTS = -DTRACE -DENAGLO -DENAQZS -DENAGAL -DENACMP -DENAIRN -DNFREQ=5 -DNEXOBS=5
CFLAGS = -Wall -O3 -ansi -pedantic -Wno-unused-but-set-variable -I$(SRC) $(OPTS) -g
LDLIBS =
OBJS = cssr2ssr.o cssr.o rtkcmn.o rtcm.o rtcm2.o rtcm3.o rtcm3e.o
cssr2ssr.exe : $(OBJS)
$(CC) -o cssr2ssr $(OBJS) $(LDLIBS)
cssr2ssr.o : ../cssr2ssr.c
$(CC) -c $(CFLAGS) ../cssr2ssr.c
cssr.o : ../cssr.c
$(CC) -c $(CFLAGS) ../cssr.c
rtkcmn.o : $(SRC)/rtkcmn.c
$(CC) -c $(CFLAGS) $(SRC)/rtkcmn.c
rtcm.o : $(SRC)/rtcm.c
$(CC) -c $(CFLAGS) $(SRC)/rtcm.c
rtcm2.o : $(SRC)/rtcm2.c
$(CC) -c $(CFLAGS) $(SRC)/rtcm2.c
rtcm3.o : $(SRC)/rtcm3.c
$(CC) -c $(CFLAGS) $(SRC)/rtcm3.c
rtcm3e.o : $(SRC)/rtcm3e.c
$(CC) -c $(CFLAGS) $(SRC)/rtcm3e.c
cssr2ssr.o : $(SRC)/rtklib.h
cssr.o : $(SRC)/rtklib.h
rtkcmn.o : $(SRC)/rtklib.h
rtcm.o : $(SRC)/rtklib.h
rtcm2.o : $(SRC)/rtklib.h
rtcm3.o : $(SRC)/rtklib.h
rtcm3e.o : $(SRC)/rtklib.h
install :
cp cssr2ssr $(BINDIR)
clean :
rm cssr2ssr
rm *.o
Just like building rnx2rtkp
, pass this file as an argument to the make
command. This will generate cssr2ssr
in the bin
directory.
make -f makefile.linux
make -f makefile.linux install
Running the sample
The rnx2rtkp created in this way can be executed using command line arguments, just like in High-precision GPS positioning with MADOCALIB, but here we will convert the batch file in the sample_data
directory into a bash shell script and execute it.
Move to the sample_data
directory and create exec_ppp.sh
, exec_pppar.sh
and exec_pppar_ion.sh
corresponding to exec_ppp.bat
, exec_pppar.bat
and exec_pppar_ion.bat
as follows. For shell scripts that do not specify the antenna phase center file igs20.atx
, add the file specification with the -ant
option.
sample_data/exec_ppp.sh
#!/bin/bash
# This is a sample BAT file that executes ppp from 00min00sec to 59min30sec every hour
BIN=../bin/rnx2rtkp
CONF=../app/consapp/rnx2rtkp/gcc_mingw/sample.conf
OBS=./TSK200JPN_S_20241620000_01D_30S_MO.rnx
NAV=./TSK200JPN_S_20241620000_01D_MN.rnx
L6E=./2024162all.204.l6
ANT=./igs20.atx
OUT=./result
mkdir -p $OUT
for H in {00..23}; do
$BIN -k $CONF -ts 2024/06/10 $H:00:00 -te 2024/06/10 $H:59:30 $OBS $NAV $L6E -o $OUT/ppp_20240610$H.pos -ant $ANT -x 2
done
sample_data/exec_pppar.sh
#!/bin/bash
# This is a sample BAT file that executes ppp-ar from 00min00sec to 59min30sec every hour
BIN=../bin/rnx2rtkp
CONF=../app/consapp/rnx2rtkp/gcc_mingw/sample_pppar.conf
OBS=./TSK200JPN_S_20241620000_01D_30S_MO.rnx
NAV=./TSK200JPN_S_20241620000_01D_MN.rnx
L6E=./2024162all.204.l6
ANT=./igs20.atx
OUT=./result
mkdir -p $OUT
for H in {00..23}; do
$BIN -k $CONF -ts 2024/06/10 $H:00:00 -te 2024/06/10 $H:59:30 -ant $ANT $OBS $NAV $L6E -o $OUT/pppar_20240610$H.pos -x 2
done
sample_data/exec_pppar_ion.sh
#!/bin/bash
# This is a sample BAT file that executes ppp-ar with ionospheric correction
# from 00min00sec to 59min30sec every hour
BIN=../bin/rnx2rtkp
CONF=../app/consapp/rnx2rtkp/gcc_mingw/sample_pppar_iono.conf
OBS=./TSK200JPN_S_20241620000_01D_30S_MO.rnx
NAV=./TSK200JPN_S_20241620000_01D_MN.rnx
L6E=./2024162all.204.l6
ANT=./igs20.atx
OUT=./result
# for Japan and Eastern Australia Region
L6D2=./2024162all.201.l6
# for Southeast Asia and Western Australia Region
L6D1=./2024162all.200.l6
mkdir -p $OUT
for H in {00..23}; do
$BIN -k $CONF -ts 2024/06/10 $H:00:00 -te 2024/06/10 $H:59:30 $OBS $NAV $L6E -mdciono $L6D1 -mdciono $L6D2 -ant $ANT -o $OUT/pppar_ion_20240610$H.pos -x 2
done
After creating these files, grant them permission to run by running chmod 755 exec_ppp.sh exec_pppar.sh exec_pppar_ion.sh
. For example, executing ./exec_ppp.sh
, we will obtain the results in the result
directory.
Let us try another application cssr2ssr
. We try to convert the CSSR file 2024162all.204.l6
in this sample to the RTCM SSR file 2024162all.rtcm
.
../bin/cssr2ssr 2024162all.204.l6 -o 2024162all.rtcm
cssr2ssr (0487):
reading... 2024162all.204.l6
finished
First, we will try to perform single positioning using the satellite orbit file TSK200JPN_S_20241620000_01D_MN.rnx
and the observation file TSK200JPN_S_20241620000_01D_30S_MO.rnx
found here.
../bin/rnx2rtkp -p 0 TSK200JPN_S_20241620000_01D_*
% program : rnx2rtkp ver.2.4.3 b34
% inp file : TSK200JPN_S_20241620000_01D_30S_MO.rnx
% inp file : TSK200JPN_S_20241620000_01D_MN.rnx
% satantfile:
% rcvantfile:
% obs start : 2024/06/10 00:00:00.0 GPST (week2318 86400.0s)
% obs end : 2024/06/10 23:59:30.0 GPST (week2318 172770.0s)
%
% (lat/lon/height=WGS84/ellipsoidal,Q=1:fix,2:float,3:sbas,4:dgps,5:single,6:ppp,ns=# of satellites)
% GPST latitude(deg) longitude(deg) height(m) Q ns sdn(m) sde(m) sdu(m) sdne(m) sdeu(m) sdun(m) age(s) ratio
2318 86400.000 36.105582210 140.087105580 87.6496 5 12 4.4032 3.7796 10.3945 0.4904 -2.0305 -4.8329 0.00 0.0
2318 86430.000 36.105576871 140.087101426 89.7484 5 12 4.4158 3.7734 10.4132 0.4356 -1.9986 -4.8626 0.00 0.0
...
Single positioning was completed. Next, we will try to perform PPP positioning using the RTCM SSR file 2024162all.rtcm
created here.
../bin/rnx2rtkp -k ../app/consapp/rnx2rtkp/gcc_mingw/sample.conf -ant igs20.atx -p 6 -x 2 TSK200JPN_S_20241620000_01D_* 2024162all.rtcm
processing : 2024/06/10 00:00:00 Q=0
2 no ssr orbit correction: 2024/06/10 00:00:00 sat= 2
2 no ssr orbit correction: 2024/06/10 00:00:00 sat= 3
2 no ssr orbit correction: 2024/06/10 00:00:00 sat= 7
...
2 no ssr orbit correction: 2024/06/10 00:00:00 sat=102
2 00:00:00.00: point pos error (lack of valid sats ns=5)
processing : 2024/06/10 00:00:30 Q=0
2 no ssr orbit correction: 2024/06/10 00:00:30 sat= 2
...
I created an RTCM SSR file and ran PPP positioning, but no solution was found. It seems that the RTCM SSR file was not loaded correctly. I will look into this further.
Also, in the process of loading this 2024162all.rtcm
with rtcmread.py
in the QZS L6 Tool, I found a bug in rtcmread.py
. I will fix this as well.
Conclusion
I built MADOCALIB version 1.4 on a Mac and ran rnx2rtkp
. I also ran a sample. I confirmed that it is possible to run not only PPP, but also PPP-AR and PPP using wide-area ionospheric information. I will look into how to use cssr2ssr
.