High-precision GPS positioning using CLASLIB
Introduction
I am considering precise point positioning (PPP) as a high-precision satellite positioning method.
The PPP information broadcast by Japan’s Quasi-Zenith Satellite System (QZSS), petnamed Michibiki, includes MADOCA-PPP (multi-GNSS advanced orbit and clock augmentation - precise point positioning) and CLAS (centimeter level augmentation service), both of which are transmitted using bi-phase shift keying (BPSK) in the L6 frequency band (a center frequency of 1278.75 MHz, a bandwidth of 42 MHz).
The Cabinet Office, Government of Japan has released these signal processing software as open source software on GitHub, and there is MADOCALIB (MADOCA-PPP test library) for MADOCA-PPP, and CLASLIB (CLAS test library) for CLAS. Because I have experimented with MADOCALIB ver.1.2, so this time I will try CLASLIB v.0.7.3a on a Windows PC.
Download and Configuration
CLASLIB consists of the following applications:
ssr2osr (state space representation to observation state representation)
ssr2obs (state space representation to observation)
rnx2rtkp (RINEX to RTK post processing)
CLASLIB was previously available on the Michibiki website. At that time, rnx2rtkp was not included in the download version of CLASLIB, and an application was required to obtain the binary file or source code. rnx2rtkp is an extension of the application of the same name in RTKLIB, and can estimate coordinates with higher accuracy than SSR2OSR by using AR (ambiguity resolution). In the past, I have tried the downloadable versions of CLASLIB, ssr2osr and ssr2obs.
CLASLIB has become open source software and has been released on GitHub along with the source code for rnx2rtkp
. This time, we will focus on rnx2rtkp
. The GitHub version of CLASLIB contains not only the source code for rnx2rtkp
but also binary files, so we will use this.
You can download CLASLIB directly from this GitHub page, but here we will install the git
command on a Windows PC and download it. git pull
can be used to update to the latest version, which is convenient for version upgrades. We will also need a development environment with commands such as make
, so we will also install MSYS2
. To install these, we will use winget
, a package manager that comes standard with Windows. Enter the following commands at the command prompt.
winget upgrade --all
winget install git.git msys2.msys2
Then, for example in your Documents folder, download CLASLIB using the git
command from the command prompt.
cd Document
git clone https://github.com/QZSS-Strategy-Office/claslib
Next, start MSYS2’s MSYS2 MINGW64
and install make
, which is necessary for testing the operation, in this shell development environment.
pacman -S make
You will be asked to confirm the installation, so enter y
. To exit MINGW64
, enter logout
or ctrl
+d
(hold down the control key and press D). Now you are ready to try CLASLIB’s rnx2rtkp
.
Processing sample data from CLASLIB
First, in the MINGW64 shell, navigate to util/rnx2rtkp in the folder where you downloaded CLASLIB.
cd /c/Users/sat/Documents/claslib/util/rnx2rtkp
In the cd
command, please replace sat
with your username. Folder names do not seem to be case sensitive in this shell. When entering a folder name, press tab
after typing partway through to complete the name. If an incorrect folder name is completed, press tab
repeatedly until the correct folder name appears.
There are several processing examples below, but in terms of CLAS positioning, the most important one is test_ST12
, which performs positioning using three input files: a satellite navigation (NAV: navigation) file, a receiver observation (OBS: observation) file, and a CLAS L6 file of subtype 12.
test_L6
First, run test_L6
with the make
command. This means that the target test_L6
written in the makefile
is executed. For a sample of the received data, CLAS performs decoding of the L6D signal broadcast. This L6 data is in the old format, using subtype (ST) 9 to represent regional tropospheric delay information. Currently, ST12 is used instead of ST9.
sat@horse MINGW64 /c/Users/sat/Documents/claslib/util/rnx2rtkp
$ make test_L6
./rnx2rtkp.exe -ti 1 -ts 2019/08/27 16:00:00 -te 2019/08/27 16:59:59 -x 2 -k kinematic.conf ..\\..\\data\\0627239Q.obs ..\\..\\data\\sept_2019239.nav ..\\..\\data\\2019239Q.l6 -o 0627239Q_claslib_L6.nmea
CSSR frame first recieve: tow=444652.2
L6 data: change facility, week=2323, tow=444652.16, ---> 1(193)
start CSSR decoding: week=2323, tow=444652.2
pos est: pos=36.104 140.086
selected_grid1: inet=7, weight=0.36, pos=35.850 140.030, dist=28.69km, index=16
selected_grid2: inet=7, weight=0.32, pos=36.390 140.030, dist=32.28km, index=17
selected_grid3: inet=7, weight=0.17, pos=35.850 140.690, dist=61.20km, index=19
selected_grid4: inet=7, weight=0.16, pos=36.390 140.690, dist=62.96km, index=20
This make
will generate and execute a command that performs CLAS positioning:
- at 1 second intervals (
-ti 1
), - from 16:00:00UTC to 16:59:59UTC on August 27, 2019 (
-ts
and-te
options), - that creates a detailed debug information file (
-x 2
, a text file with the extension trace is created), - that uses the configuration file
kinematic.conf
(-k kinematic.conf
), - that uses the OBS file
0227239Q.obs
in..\..\data\
(..\\..\\data\\0227239Q.obs
), - that uses the NAV file
sept_2019239.nav
in..\..\data\
(..\..\data\sept_2019239.nav
), - that uses the CLAS L6 file
2019239Q.l6
in..\..\data\
(..\..\data\20119239Q.l6
), and - that outputs the results to the
0627239Q_claslib_L6.nmea
file (-o 0627239Q.nmea
).
This command sequence can also be executed in a shell environment.
In the process of this positioning, rnx2rtkp finds the rough coordinates of the receiver, 36.104 degrees north and 140.086 degrees east, finds the appropriate Network ID (NID) 7 in the CLAS grid, and calculates the tropospheric delay weighted by the distance between the rough coordinates of the receiver and the four surrounding coordinates contained within this NID.
The coordinate output is in NMEA-0183 (National Marine Electronics Association) format. It is somewhat difficult for us to associate the results with the actual coordinates. If you change out-solformat
to llh
(latitude, longitude, and elliptical height) and out-timesys
to utc
in the configuration file kinematic.conf
, the coordinates and time will be easier to read. Here, we will plot with rtkplot.exe
in the NMEA format directly. After starting rtkplot.exe
, display the options screen by pressing Edit
→Options..
(or ctrl
+p
). Here, change Show Statistics
to ON
to output statistical information, and change Coordinate Origin
to End Pos
to set the origin to the final time coordinate assuming that it will converge to the correct value over time, and press OK
.
Then, select 0627239Q.nmea
from File
→Open Solution-1...
and plot it.
If you change the display mode of rtkplot
from Gnd Trk
(ground track) to Position
, you will see the change in coordinates over time.
The bottom of the screen shows that 99.9% of the total is in the fixed state (Q=1), and 0.1% is in the float state (Q=2). The statistical information in the upper right also shows that the latitude is 36.103633678 degrees north, longitude is 140.086318713 degrees east, and the ellipsoid height is 69.7940 meters. If you search for these coordinates on the Geospatial Information Authority of Japan’s GSI Map, you will see that it is near the Geospatial Information Authority of Japan’s “Map and Survey Science Museum.”
On the other hand, from the file name 0627239Q.obs
, this seems to be an OBS file of session numberQ (from 16:00:00UTC to 16:59:59UTC) on the 239th day from January 1st (August 27th in 2019) of the CORSs station number 0627
. If you search for the station number 0627
on the Geospatial Information Authority of Japan’s CORSs data provision service, you will find that the receiver of this station was first installed in 1996, and its approximate coordinates are 36.10363585N and 140.08630753E.
The circumference of the Earth is about 40,000 km, so one degree of latitude is equivalent to about 111 km. The difference between the latitude of 36.103633678 degrees calculated by CLAS and the latitude of 36.10363585 degrees of station number 0627
is 2.18×10-6, so there is a difference of about 24 centimeters in the north-south direction. These reference point coordinates are approximate values, and there is also crustal movement over time between the two, so it can be said that they are almost the same.
test_L6_week
Next, let’s run test_L6_week
. This example is for processing data for one hour from 00:00:00 UTC on November 25, 2018. The -l6w
option here is to specify the GPS week number (page 15).
sat@horse MINGW64 /c/Users/sat/Desktop/claslib/util/rnx2rtkp
$ make test_L6_week
./rnx2rtkp.exe -ti 1 -ts 2018/11/25 0:00:00 -te 2018/11/25 00:59:59 -l6w 2028 -x 2 -k kinematic.conf ..\\..\\data\\0161329A.obs ..\\..\\data\\tskc2018329.nav ..\\..\\data\\2018328X_329A.l6 -o 0161329A_claslib_L6W.nmea
CSSR frame first recieve: tow=445122.9
L6 data: change facility, week=2323, tow=445122.90, ---> 1(193)
start CSSR decoding: week=2323, tow=445122.9
pos est: pos=39.981 141.225
selected_grid1: inet=9, weight=0.43, pos=40.160 141.340, dist=22.25km, index=12
selected_grid2: inet=9, weight=0.23, pos=39.620 141.340, dist=41.32km, index=11
selected_grid3: inet=9, weight=0.19, pos=40.160 140.690, dist=49.82km, index=7
selected_grid4: inet=9, weight=0.16, pos=39.620 140.690, dist=60.78km, index=6
Let’s plot this result using rtkplot as well.
test_L6_bnx
This is an example of using a BINEX (binary exchange format) file instead of a text-format RINEX (receiver independent exchange format) OBS file as the receiver observation file. RTKLIB and CLASLIB can also read BINEX files. The date and time are one hour from 16:00:00 UTC on the 239th day (August 27th) from January 1st, 2019, the same as the previous test_L6
.
sat@horse MINGW64 /c/Users/sat/Desktop/claslib/util/rnx2rtkp
$ make test_L6_bnx
./rnx2rtkp.exe -ti 1 -ts 2019/08/27 16:00:00 -te 2019/08/27 16:59:59 -x 2 -k kinematic.conf ..\\..\\data\\0627239Q.bnx ..\\..\\data\\sept_2019239.nav ..\\..\\data\\2019239Q.l6 -o 0627239Q_claslib_L6B.nmea
CSSR frame first recieve: tow=445241.3
L6 data: change facility, week=2323, tow=445241.26, ---> 1(193)
start CSSR decoding: week=2323, tow=445241.3
pos est: pos=36.104 140.086
selected_grid1: inet=7, weight=0.36, pos=35.850 140.030, dist=28.69km, index=16
selected_grid2: inet=7, weight=0.32, pos=36.390 140.030, dist=32.28km, index=17
selected_grid3: inet=7, weight=0.17, pos=35.850 140.690, dist=61.20km, index=19
selected_grid4: inet=7, weight=0.16, pos=36.390 140.690, dist=62.96km, index=20
test_VRS
This example is not based on CLAS positioning. Instead of giving an L6 file, RTK positioning is performed for the mobile station using three files, the NAV file, the OBS file for the mobile station, and the OBS file for the reference station, just like RTK. Here, we use a virtual reference station (VRS: virtual reference station) created by CLASLIB’s ssr2obs. In the configuration file kinematic_vrs.conf
used here, the positioning mode pos1-posmode
is set to vrs-rtk
.
sat@horse MINGW64 /c/Users/sat/Desktop/claslib/util/rnx2rtkp
$ make test_VRS
./rnx2rtkp.exe -ti 1 -ts 2019/08/27 16:00:00 -te 2019/08/27 16:59:59 -x 2 -k kinematic_vrs.conf ..\\..\\data\\0627239Q.obs ..\\..\\data\\sept_2019239.nav ..\\..\\data\\vrs2019239Q.obs -o 0627239Q_claslib_VRS.nmea
This result shows that VRS is not used and all positioning is independent (Q=5). This is because there is no VRS OBS file vrs2019239Q.obs
in the folder ../../data/
. If you put vrs2019239Q.obs created by the following ssr2obs here and run it again, you can perform RTK positioning using CLAS VRS.
test_ST12
The following is an example using ST12, which is currently broadcast on CLAS, instead of ST9 mentioned above. This is data for one hour from 01:00:00 UTC on December 15, 2019. ST12 message broadcasting will start at 06:00:00 UTC on November 30, 2020. Therefore, this L6 file is test data before broadcast from Michibiki. With this format change from ST9 to ST12, the number of satellites that can be augmented has increased from a maximum of 11 to a maximum of 17.
sat@horse MINGW64 /c/Users/sat/Desktop/claslib/util/rnx2rtkp
$ make test_ST12
./rnx2rtkp.exe -ti 1 -ts 2019/12/15 01:00:00 -te 2019/12/15 01:59:59 -x 2 -k kinematic.conf ..\\..\\data\\0627349AB.bnx ..\\..\\data\\sept_2019349.nav ..\\..\\data\\2019349B.l6 -o 0627349AB_claslib_ST12.nmea
CSSR frame first recieve: tow=445311.3
L6 data: change facility, week=2323, tow=445311.34, ---> 1(193)
start CSSR decoding: week=2323, tow=445311.3
pos est: pos=36.104 140.086
selected_grid1: inet=7, weight=0.36, pos=35.850 140.030, dist=28.69km, index=16
selected_grid2: inet=7, weight=0.32, pos=36.390 140.030, dist=32.28km, index=17
selected_grid3: inet=7, weight=0.17, pos=35.850 140.690, dist=61.20km, index=19
selected_grid4: inet=7, weight=0.16, pos=36.390 140.690, dist=62.96km, index=20
As time passes, we can see that the satellite goes from independent positioning (Q=5) to RTK float state (Q=2) to fixed state (Q=1), and then remains in the fixed state.
test_NONAV
CLAS positioning requires three files: an OBS file, a NAV file, and a CLAS L6 file. This is an example of how CLAS positioning can be done without an explicit NAV file.
sat@horse MINGW64 /c/Users/sat/Desktop/claslib/util/rnx2rtkp
$ make test_NONAV
./rnx2rtkp.exe -ti 1 -ts 2019/12/15 01:00:00 -te 2019/12/15 01:59:59 -x 2 -k kinematic.conf ..\\..\\data\\0627349AB.bnx ..\\..\\data\\2019349B.l6 -o 0627349AB_claslib_NONAV.nmea
CSSR frame first recieve: tow=445363.1
L6 data: change facility, week=2323, tow=445363.10, ---> 1(193)
start CSSR decoding: week=2323, tow=445363.1
pos est: pos=36.104 140.086
selected_grid1: inet=7, weight=0.36, pos=35.850 140.030, dist=28.69km, index=16
selected_grid2: inet=7, weight=0.32, pos=36.390 140.030, dist=32.28km, index=17
selected_grid3: inet=7, weight=0.17, pos=35.850 140.690, dist=61.20km, index=19
selected_grid4: inet=7, weight=0.16, pos=36.390 140.690, dist=62.96km, index=20
I thought it was amazing that it could determine position without a NAV file, but it turns out that this BINEX file contains not only an OBS file, but also a NAV file.
$ convbin 0627239Q.bnx
input file : 0627239Q.bnx (BINEX)
->rinex obs : 0627239Q.obs
->rinex nav : 0627239Q.nav
->sbas log : 0627239Q.sbs
scanning: 2019/08/27 17:00:16 GREJ
2019/08/27 16:00:20-08/27 17:00:18: O=3599 N=85
The contents of 0627239Q.nav
are as follows.
3.04 N: GNSS NAV DATA M: Mixed RINEX VERSION / TYPE
CONVBIN 2.4.3 20240725 111126 UTC PGM / RUN BY / DATE
format: BINEX COMMENT
log: 0627239Q.bnx COMMENT
END OF HEADER
G26 2019 08 27 18 00 00 .251140445471D-04 .898126018001D-11 .000000000000D+00
.500000000000D+02 .709687500000D+02 .431053669401D-08 .118650858810D+01
.376068055630D-05 .382131396327D-02 .117458403111D-04 .515366663933D+04
.237600000000D+06 -.596046447754D-07 -.451940986528D+00 .894069671631D-07
.950545623389D+00 .146406250000D+03 .136580094595D+00 -.788532845558D-08
-.261439461432D-09 .100000000000D+01 .206800000000D+04 .000000000000D+00
.200000000000D+01 .000000000000D+00 .745058059692D-08 .500000000000D+02
.230418000000D+06 .400000000000D+01
...
test_ST12_VRS
This is an example of RTK positioning using CLAS VRS on ST12, currently being broadcast on CLAS.
sat@horse MINGW64 /c/Users/sat/Documents/claslib/util/rnx2rtkp
$ make test_ST12_VRS
./rnx2rtkp.exe -ti 1 -ts 2019/12/15 01:00:00 -te 2019/12/15 01:59:59 -x 3 -k kinematic_vrs.conf ..\\..\\data\\0627349AB.bnx ..\\..\\data\\sept_2019349.nav ..\\..\\data\\vrs2019349B.obs -o 0627349AB_claslib_VRS_ST12.nmea
As with test_VRS
in ST9, this ST12 example is a standalone positioning because there is no VRS OBS file vrs2019349B.obs
. RTK positioning was achieved by placing vrs2019349B.obs created using the following method in the data
folder.
I compared CLAS positioning using rnx2rtkp
alone with RTK positioning using VRS created with ssr2obs
. I applied CLAS positioning to Solution-1 of rtkplot
and RTK positioning to Solution-2.
Next, select Q=1 to compare only the Fix state. The results are almost identical between the CLAS positioning described above and the VRS-RTK positioning using ssr2obs.
Creating VRS receiver observation files using ssr2obs
Using the NAV file and CLAS L6 file, you can create a VRS OBS file at any point. To use ssr2obs, you need to compile the source code. In the MSYS2 MINGW64
shell, install the C compiler gcc
with pacman -S gcc
and compile ssr2obs with make
.
sat@horse MINGW64 /c/Users/sat/Documents/claslib/util/rnx2rtkp
$ cd ../ssr2obs
sat@horse MINGW64 /c/Users/sat/Documents/claslib/util/ssr2obs
$ pacman -S gcc
...
sat@horse MINGW64 /c/Users/sat/Documents/claslib/util/ssr2obs
$ make
...
sat@horse MINGW64 /c/Users/sat/Documents/claslib/util/ssr2obs
Once you have compiled it, you can test it. make test1r
will create an OBS file from the ST9 CLAS L6 file, and make test1r_ST12
will create an OBS file from the ST12 CLAS L6 file.
sat@horse MINGW64 /c/Users/sat/Documents/claslib/util/ssr2obs
$ make test1r
./ssr2obs.exe -k sample.conf -ts 2019/08/27 16:00:00 -te 2019/08/27 16:59:59 -ti 1 ..\\..\\data\\sept_2019239.nav ..\\..\\data\\2019239Q.l6 -r -o ..\\..\\data\\vrs2019239Q.obs
CSSR frame first recieve: tow=459950.9
L6 data: change facility, week=2323, tow=459950.87, ---> 1(193)
start CSSR decoding: week=2323, tow=459950.9
pos est: pos=36.104 140.086
selected_grid1: inet=7, weight=0.36, pos=35.850 140.030, dist=28.69km, index=16
selected_grid2: inet=7, weight=0.32, pos=36.390 140.030, dist=32.28km, index=17
selected_grid3: inet=7, weight=0.17, pos=35.850 140.690, dist=61.20km, index=19
selected_grid4: inet=7, weight=0.16, pos=36.390 140.690, dist=62.96km, index=20
sat@horse MINGW64 /c/Users/sat/Documents/claslib/util/ssr2obs
$ make test1r_ST12
./ssr2obs.exe -k sample.conf -ts 2019/12/15 01:00:00 -te 2019/12/15 01:59:59 -ti 1 ..\\..\\data\\sept_2019349.nav ..\\..\\data\\2019349B.l6 -r -o ..\\..\\data\\vrs2019349B.obs
CSSR frame first recieve: tow=459967.4
L6 data: change facility, week=2323, tow=459967.37, ---> 1(193)
start CSSR decoding: week=2323, tow=459967.4
pos est: pos=36.104 140.086
selected_grid1: inet=7, weight=0.36, pos=35.850 140.030, dist=28.69km, index=16
selected_grid2: inet=7, weight=0.32, pos=36.390 140.030, dist=32.28km, index=17
selected_grid3: inet=7, weight=0.17, pos=35.850 140.690, dist=61.20km, index=19
selected_grid4: inet=7, weight=0.16, pos=36.390 140.690, dist=62.96km, index=20
If we look at the end of the option file sample.conf
specified in ssr2obs
, we can see that the VRS coordinates are defined as 36.103633852777776 degrees north latitude, 140.086318405555573 degrees east longitude, and 69.770420000000001 meters ellipsoidal height.
# Positions of virtual reference station
ant1-postype =llh # (0:llh,1:xyz)
ant1-pos1 =36.103633852777776
ant1-pos2 =140.086318405555573
ant1-pos3 =69.770420000000001
The VRS coordinates do not have to be exact; for example, you can get almost identical results with only three decimal places. However, if you have rnx2rtkp, you can get CLAS positioning without creating a VRS, therefore, you may not need ssr2obs very often.
CLAS positioning using own data
Currently, CLASLIB requires multiple files, such as grid files. For positioning, and the locations of these files are specified in the configuration file. Also, since CLASLIB requires many settings, the -k
option is required to load the configuration file. I would like to hard-code the grid files, ocean tide files, receiver-specific signal delay tables, and antenna phase center files, and set default values so that positioning can be performed without providing a configuration file.
Therefore, if you want to use CLASLIB for CLAS positioning, it is easy to collect the NAV file, OBS file, and CLAS L6 file in the util/rnx2rtkp
folder and run rnx2rtkp
in this folder. The CLAS L6 file can be downloaded by searching the date and time from the CLAS Data Archive at Michibiki official website.
As an example, we will analyze data 20240703a.gps observed for one hour from 00:00:00 UTC on July 3, 2024 using the NovAtel OEM729 receiver used in the MADOCALIB experiment. We will also download the CLAS L6 file 2024185A.l6 which contains augmentation information for this date and time.
In addition, RTKLIB’s convbin.exe
is also placed in this util/rnx2rtkp
folder, and executed with the -os
option, which records the satellite signal reception strength in the OBS file. Since CLASLIB excludes satellites with weak signal strength (pos1-snrmask
in the configuration file), satellites cannot be found from the OBS file without this option.
sat@horse MINGW64 /c/users/sat/Documents/apps/claslib/util/rnx2rtkp
$ ./convbin.exe -os 20240703a.gps
input file : 20240703a.gps (NovAtel OEM7)
->rinex obs : 20240703a.obs
->rinex nav : 20240703a.nav
->sbas log : 20240703a.sbs
scanning: 2024/07/03 01:01:37 GREJC
2024/07/03 00:01:38-07/03 01:01:37: O=3600 N=154
The NAV and OBS files created in this way are analyzed using rnx2rtkp
.
sat@horse MINGW64 /c/users/sat/Documents/apps/claslib/util/rnx2rtkp
$ ./rnx2rtkp.exe -k kinematic.conf 20240703a.nav 20240703a.obs 2024185A.l6 -o 20240703a.nmea
CSSR frame first recieve: tow=392014.5
L6 data: change facility, week=2324, tow=392014.45, ---> 2(193)
start CSSR decoding: week=2324, tow=392014.5
pos est: pos=34.440 132.415
selected_grid1: inet=5, weight=0.61, pos=34.230 132.130, dist=35.08km, index=3
selected_grid2: inet=5, weight=-0.04, pos=34.770 132.130, dist=45.08km, index=4
selected_grid3: inet=5, weight=0.43, pos=34.770 132.790, dist=50.36km, index=5
CLAS positioning was possible without specifying the options -ti
, -ts
, and -te
. Here, we will plot only for Q=1, which is the Fix state.
The coordinates of a stationary receiver on the university rooftop were determined to within a few centimetres.
In this configuration file kinematic.conf
, the receiver is set to the Trimble NetR9 receiver, and the antenna is set to the Trimble TRM59800.800, so it was necessary to change the configuration file. Also, since the data used in this analysis is not from the Geospatial Information Authority of Japan’s reference station, as written in the comments of the configuration file, it was also necessary to change the BLQ (ocean tide loading) file.
Conclusion
CLASLIB’s rnx2rtkp was used to perform CLAS positioning. Unlike MADOCALIB, CLASLIB requires multiple files such as CLAS grid files in addition to the application, and the configuration files are also complex. The rnx2rtkp
application is convenient because it can perform CLAS positioning without VRS if you have a NAV file, OBS file, and CLAS L6 file.
Related article(s):
- Quasi-zenith satellite Michibiki's positioning library CLASLIB (Part 3 VRS-RTK positioning by ssr2obs) 10th May 2020
- Quasi-zenith satellite Michibiki's positioning library CLASLIB (Part 2 ssr2osr) 8th May 2020
- Quasi-zenith satellite Michibiki's positioning library CLASLIB (Part 1 Understanding the configuration) 7th May 2020