Compact SSR display capability on QZS L6 Tool

category: gnss

Introduction

I am interested in the quasi-zenith satellite (QZS, petnamed Michibiki) operated by the Cabinet Office of Japan and am chasing its radiowaves. QZS L6 Tool, which focuses on decoding high-precision positioning messages from Michibiki, is available on GitHub.

The QZS L6 Tool can also decode CLAS (centimeter level augmentation service, pronounced as Cirrus) messages of L6D signals broadcast by Michibiki in the L6 frequency band. I have also prepared sample data, so if you are interested, please try it. I will prepare the documents and improve them little by little.

Regarding CLAS, the CLAS test library CLASLIB, which performs message decoding and positioning calculation, has been released on the Michibiki official page, and VRSC receiver that can generate virtual reference stations is also on sale from BizStation.

In contrast, the QZS L6 Tool focused on message observation. I wrote this Python code while reading the specifications, so it is independent from CLASLIB. Since the BSD 2-clause license is applied to the tool, this code can be used regardless of commercial or non-commercial use and with or without modification.

Compact SSR, highly compressed state space representation messages

For example, when using RTK (realtime kinematic), which is one method of high-precision satellite positioning, binary data transmission in RTCM (Radio Technical Commission for Maritime Services) format is widely used. The reason for developing the QZS L6 Tool was that I wanted to see the contents of these messages. The QZS L6 Tool started decoding RTCM messages and MADOCA (multi-GNSS advanced demonstration tool for orbit and clock analysis) binary format messages sent on L6E signals.

There are two approaches to improving positioning accuracy: OSR (observation space representation) and SSR (state space representation). The former includes RTK that utilize satellite signal observations at reference stations. MADOCA and CLAS are the latter approaches.

RTCM messages that carry SSR information are also defined. MADOCA paid product service by Global Positioning Service Co., Ltd. (GPAS), real-time service of IGS (International GNSS Service) (example of use by Professor Ebinuma of Chubu University), and previous MADOCA free product by JAXA (example of use) deliver SSR messages in RTCM message format via the Internet. The message format of the MADOCA free product on the Michibiki L6E signal published by GPAS (English version specification).

RTCM messages are somewhat redundant for SSR information transmission. Compact SSR (CSSR) is a binary format message designed to reduce the transmission capacity of SSR information as much as possible. To transmit CSSR in RTCM format, use message type number 4073 owned by Mitsubishi Electric Corporation. The new MADOCA-PPP, which is scheduled to be broadcast from Michibiki on a trial basis from September 30, 2022, will use the CSSR format in the specification IS-QZSS-MDC-001. I wrote this code to experience CSSR. From now on, CSSR may be widely used.

The specification IS-QZSS-MDC-001 has a description of the signal authentication message QZNMA (quasi-zenith satellite navigation message authentication), and its vendor ID (signal type code) is also defined, but the format is specified. The specification IS-QZSS-SAS (signal authentication service) has not been published yet.

message flows from observation, service provider, and quasi-zenith satellites

Rather than using all messages in their original format, it seems more unified and convenient to convert them to RTCM format and use them.

Transmission format of Compact SSR

Michibiki’s L6 message length is 2000 bits, and one message is broadcast per second on the L6 signal channel. The content part (payload) of the L6 message is a fixed-length bit stream with a length of 1695 bits, and this part is called the “data part”. All of CLAS, MADOCA, MADOCA-PPP, and QZNMA form one unit (frame) in 30 seconds. Michibiki repeatedly transmits and updates the contents of this frame.

The CSSR messages used by CLAS and MADOCA-PPP are stored in this frame. CSSR is a variable length message that currently defines message types from subtypes 1-12. Subtype 1 CSSR messages represent the combination of satellites (eg GPS01) and signals (eg L1 C/A) to be handled in bits. On the other hand, messages other than subtype 1 do not contain this combination information and only describe the satellite orbit, satellite internal clock, and correction amount of user observation data. Therefore, decoding a CSSR message requires decoding the subtype 1 message and retaining the information on satellites and signals to be augmented.

In CSSR, multiple messages are stored in front. In addition, the CSSR has no obvious message length information and the message must be read from the beginning to decode. Multiple CSSR messages are placed consecutively in multiple data parts, and the CSSR message length varies depending on the target satellite and signal.

A CSSR subframe consists of 5 data parts. Subframes are used for data delimiter identification. For the data part that belongs to the beginning of the subframe, the “subframe indicator” in the header is turned on, and the user receiver detects the CSSR message delimiter with this flag. CSSR messages are transmitted closed within a frame and the rest are zero padded.

message format of CSSR (Message transmission example cited from the specification IS-QZSS-L6-004. The actual subtype number order was not as described here)

The CSSR subtype number assignment at the beginning of the subframe is not specified in the specifications, but a subtype 1 message is placed at the beginning of the frame. The subtype 3 messages (satellite clock) is placed at the beginning of the subframes in the middle of the frame.

After all, CSSR decode is to find the beginning of the bit steam with the subframe indicator, to reads the subtype number for the CSSR message that is finally decoded, and it takes a total of 30 seconds from decoding the message of subtype 1. In the worst case where reception starts after subtype 1 CSSR message is sent, CSSR decode starts 30 seconds after reception starts, so it takes 60 seconds to get the first full message.

Implementation of Compact SSR decode

One way to decode a CSSR message is to find out a subtype 1 data part, then receive and decode 5 consecutive data parts, and then receive and decode the subsequent 5 consecutive data parts. The status display of the BizStation VRSC receiver is updated every 5 seconds, therefore, it seems that this method is used.

Here, after discovering the subtype 1 data part, the tool reads the message while checking the number of remaining bits. After reading one CSSR message, it calculates the data size and adds CRC to create an RTCM message. If there are not enough bits left, it reads the next data part. This is because I want to display information in real time as much as possible.

In information theory, a code that can be decoded immediately after the message transmission is completed is called an instantaneous code. Since CSSR messages are classified into this instantaneous code, I aimed to create an RTCM immediately after decoding the message. In information theory, a code with obvious message delimiters is called a comma code. Therefore, CSSR is not a comma code. The current MADOCA transmitted on L6E signal channel, excluding the error correction part from the RTCM message, use byte-aligned bit stream. The current MADOCA has a part that can be called a comma code, so it is easier to decode than CSSR.

Experiment of QZS L6 Tool using sample

Preparation

Please download the QZS L6 Tool from the GitHub page. You can either download the ZIP file or use the git command. I recommend using the git command, which makes it easy to update the source code.

git clone https://github.com/yoronneko/qzsl6tool

If you have already downloaded it with the git command, you can update to the latest code by running git pull in that directory.

Michibiki CLAS archive

CLAS archive data can be obtained from the Michibiki official page. The sample contains one hour’s worth of data from 00:00:00 UTC on January 1, 2022. Let’s decode this. We execute qzsl62rtcm.py (QZS L6 data to RTCM conversion) in the python directory of the QZS L6 Tool.

$ cat ../sample/2022001A.l6 | ./qzsl62rtcm.py | more
193 Hitachi-Ota:0  CLAS SF1 DP1 ST1 ST3 ST2
193 Hitachi-Ota:0  CLAS SF1 DP2 ST4 ST7 ST11 ST6
193 Hitachi-Ota:0  CLAS SF1 DP3 ST12 ST6
193 Hitachi-Ota:0  CLAS SF1 DP4 ST12
193 Hitachi-Ota:0  CLAS SF1 DP5
193 Hitachi-Ota:0  CLAS SF2 DP1 ST3 ST11 ST6
193 Hitachi-Ota:0  CLAS SF2 DP2
193 Hitachi-Ota:0  CLAS SF2 DP3 ST12 ST6
193 Hitachi-Ota:0  CLAS SF2 DP4 ST12
193 Hitachi-Ota:0  CLAS SF2 DP5
193 Hitachi-Ota:0  CLAS SF3 DP1 ST3 ST11 ST6
193 Hitachi-Ota:0  CLAS SF3 DP2 ST12
...

This code reads the data from the standard input and displays the decode result on the standard output. From the left, the result display is the PRN number (193, QZS-1), the control station (here, Hitachi-Ota satellite control bureau), the first system (0 or 1) of the control station 2 system, the vendor ID (CLAS), and the subframe number ( You can see that SF1), the data part number (DP1), and this data part contains information of subtypes 1, 3, and 2. For messages that are consecutive in multiple data parts, the subtype number (such as ST1) is displayed at the later data part.

Specifying a natural number with the trace option -t will display more detailed information.

$ cat ../sample/2022001A.l6 | ./qzsl62rtcm.py -t 1 | more
ST1 G05 L1 C/A L2 L2C(M+L) L2 Z-tracking
ST1 G13 L1 C/A L2 Z-tracking
ST1 G14 L1 C/A L2 L2C(M+L) L2 Z-tracking L5 I+Q
ST1 G15 L1 C/A L2 L2C(M+L) L2 Z-tracking
ST1 G18 L1 C/A L2 L2C(M+L) L2 Z-tracking L5 I+Q
ST1 G20 L1 C/A L2 Z-tracking
ST1 G23 L1 C/A L2 L2C(M+L) L2 Z-tracking L5 I+Q
ST1 G24 L1 C/A L2 L2C(M+L) L2 Z-tracking L5 I+Q
ST1 E02 E1 B+C E5a I+Q
ST1 E03 E1 B+C E5a I+Q
ST1 E05 E1 B+C E5a I+Q
ST1 E08 E1 B+C E5a I+Q
ST1 E13 E1 B+C E5a I+Q
ST1 E15 E1 B+C E5a I+Q
ST1 E24 E1 B+C E5a I+Q
ST1 E25 E1 B+C E5a I+Q
ST1 J02 L1 C/A L2 L2C(M+L) L5 I+Q
ST1 J03 L1 C/A L2 L2C(M+L) L5 I+Q
ST3 G05  0.5
ST3 G13  0.1
...
ST3 J02 -0.3
ST3 J03  0.2
ST2 G05 IODE= 74 radial=-0.1 along=-0.3 cross=-0.3
ST2 G13 IODE= 13 radial= 0.1 along= 0.2 cross= 0.2
ST2 G14 IODE= 23 radial= 0.2 along= 0.7 cross= 0.7
ST2 G15 IODE= 71 radial= 0.1 along= 0.3 cross= 0.3
...

Trace-on displays a lot of information. In this example, the first subtype 1 (ST1) message is the L1 C/A signal of GPS05, the L2C(M+L) signal, and the L2 Z-tracking. It did not contain information about L5 band signals. The ST3 message describes the time correction amount for each satellite, and the ST2 message describes the orbit correction amount for each satellite. It is also possible to record these messages to a file. If we read this message decoding result with reference to the specification IS-QZSS-L6-004 and the web information, we can see the backyard of the CLAS high-precision receiver.

Also, specify the option -r to convert the CLAS decode result to an RTCM message. The tool to decipher RTCM messages is showrtcm.py. However, there seems to be no code that can utilize the CSSR RTCM file for positioning yet. This option prevents the status message from being output, but the -m option displays the status message in the standard error output.

cat ../sample/2022001A.l6 | ./qzsl62rtcm.py -r > clas.rtcm
cat clas.rtcm | ./showrtcm.py | more
RTCM 4073   CSSR ST1       epoch=518400 iod=13
RTCM 4073   CSSR ST3       hepoch=0 iod=13
RTCM 4073   CSSR ST2       hepoch=0 iod=13
RTCM 4073   CSSR ST4       hepoch=0 iod=13
RTCM 4073   CSSR ST7       hepoch=0 iod=13
...

With pipes, we don’t have to create an intermediate file clas.rtcm.

cat ../sample/2022001A.l6 | ./qzsl62rtcm.py -r | showrtcm.py | more
RTCM 4073   CSSR ST1       epoch=518400 iod=13
RTCM 4073   CSSR ST3       hepoch=0 iod=13
RTCM 4073   CSSR ST2       hepoch=0 iod=13
RTCM 4073   CSSR ST4       hepoch=0 iod=13
RTCM 4073   CSSR ST7       hepoch=0 iod=13
...

Currently, highly compressed subtype 12 information is being sent. Previously, subtypes 8 and 9 used to represent the amount of correction for each region. January 1, 2018 00:00:00 UTC. Therefore, we try decoding the old CLAS data.

cat ../sample/2018001A.l6 | ./qzsl62rtcm.py
193 Hitachi-Ota:0  CLAS SF1 DP1 ST1 ST3 ST2 ST4
193 Hitachi-Ota:0  CLAS SF1 DP2 ST5 ST7 ST6 ST8
193 Hitachi-Ota:0  CLAS SF1 DP3 ST9
193 Hitachi-Ota:0  CLAS SF1 DP4 ST6 ST8
193 Hitachi-Ota:0  CLAS SF1 DP5 ST9
...

Subtype 8 and subtype 9 messages were being broadcast.

Allystar HD9310 option C

Allystar HD9310 Option C has two types of firmware, CLAS reception firmware and MADOCA reception firmware, and they are exclusively used. I have two of these receivers, one for CLAS reception and one for MADOCA reception. The Allystar receiver can simultaneously receive up to 4 satellites of the Michibiki L6 signal. At present, all Michibi satellites broadcast the same L6 information, so here we are using the information from the satellite with the highest signal strength.

allystar receiver signal processing

First, we use observation data with the Allystar receiver recorded by the MADOCA firmware of HD9310 receiver for 1 minute from 23:12:00 UTC on March 26, 2021.

cat ../sample/20220326-231200mdc.alst | alst2qzsl6.py | more
209 2022-03-26 23:12:00 43
206 2022-03-26 23:12:00 43
205 2022-03-26 23:12:00 37 RS
204 2022-03-26 23:12:00 43
---> prn 209 (snr 43)
209 2022-03-26 23:12:01 43
206 2022-03-26 23:12:01 43
205 2022-03-26 23:12:01 37
204 2022-03-26 23:12:01 43
...

We found the signals of QZS-2 ( PRN204), QZS-3 ( PRN209), QZS-4 ( PRN205), and QZS-1R ( PRN206). Then we decode this L6 message.

cat ../sample/20220326-231200mdc.alst | alst2qzsl6.py -l | qzsl62rtcm.py |  more
209 Hitachi-Ota:0* 2022-03-26 23:11:44 1062(26) 1068(17)
206 Hitachi-Ota:0* 2022-03-26 23:11:44 1057(8) 1061(8)
206 Hitachi-Ota:0* 2022-03-26 23:11:46 1062(26) 1068(17)
206 Hitachi-Ota:0* 2022-03-26 23:11:46 1057(8) 1061(8)
...

Similarly, we observe the binary data with the CLAS firmware.

cat ../sample/20220326-231200clas.alst | alst2qzsl6.py | more
199 2022-03-26 23:12:00 43
195 2022-03-26 23:12:00 37 RS
194 2022-03-26 23:12:00 43
196 2022-03-26 23:12:00 42
---> prn 199 (snr 43)
199 2022-03-26 23:12:01 43
195 2022-03-26 23:12:01 37 RS
194 2022-03-26 23:12:01 43
196 2022-03-26 23:12:01 42
...

The first Michibiki was put into standby operation on March 25, 2022, so PRN193 is no longer observed here.

cat ../sample/20220326-231200clas.alst | alst2qzsl6.py -l | qzsl62rtcm.py | more
199 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
196 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS SF1 DP1 ST1 ST3 ST2
196 Hitachi-Ota:1  CLAS SF1 DP2 ST4 ST7 ST11 ST6
194 Hitachi-Ota:1  CLAS SF1 DP3 ST12 ST6
196 Hitachi-Ota:1  CLAS SF1 DP4 ST12
196 Hitachi-Ota:1  CLAS SF1 DP5
194 Hitachi-Ota:1  CLAS SF2 DP1 ST3 ST11 ST6

In this example, 15 seconds after the reception start time (because it is 15 lines), a subtype 1 CLAS message was found and the decode started.

PocketSDR

Let’s process the sample data of Professor Takasu’s PocketSDR. Since it is software defined radio, we are happy that the target satellite can be freely selected by post-processing the recorded signal. We will use the 30-second L6 band data recorded by Professor Takasu at 08:22:12 UTC on December 26, 2021. By specifying the option, the MADOCA message of QZS-2 was targeted. Use the code pksdr2l6.py (PocketSDR message to L6 message conversion) to extract the L6 message from the PocketSDR message output.

cat ../sample/20211226-082212pocketsdr-mdc.txt | ./pksdr2l6.py | qzsl62rtcm.py | more
204 Hitachi-Ota:0* 2021-12-26 08:21:58 1059(24)
204 Hitachi-Ota:0* 2021-12-26 08:22:00 1062(24) 1068(17)
204 Hitachi-Ota:0* 2021-12-26 08:22:00 1059(2)
204 Hitachi-Ota:0* 2021-12-26 08:22:02 1062(24) 1068(17)
204 Hitachi-Ota:0* 2021-12-26 08:22:02 1065(19)
204 Hitachi-Ota:0* 2021-12-26 08:22:04 1062(24) 1068(17)
...
cat ../sample/20211226-082212pocketsdr-mdc.txt | ./pksdr2l6.py | qzsl62rtcm.py -r | showrtcm.py | more
RTCM 1059 G SSR code bias G01 G02 G03 G05 G06 G07 G08 G09 G10 G12 G13 G15 G16 G17 G19 G20 G21 G22 G24 G25 G26 G27 G29 G30 (nsat=24 iod=4 cont.)
RTCM 1062 G SSR hr clock  G01 G02 G03 G05 G06 G07 G08 G09 G10 G12 G13 G15 G16 G17 G19 G20 G21 G24 G25 G26 G29 G30 G31 G32 (nsat=24 iod=4)
RTCM 1068 R SSR hr clock  R01 R02 R03 R04 R05 R07 R08 R12 R13 R14 R15 R17 R18 R19 R20 R21 R22 (nsat=17 iod=5)
RTCM 1059 G SSR code bias G31 G32 (nsat=2 iod=4)
...

Next, we process the CLAS message.

cat ../sample/20211226-082212pocketsdr-clas.txt | ./pksdr2l6.py | qzsl62rtcm.py | more
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
194 Hitachi-Ota:1  CLAS
...

I was able to decode the vendor ID, but the CLAS message decode did not start because there were no subtype 1 messages observed in the last 30 seconds. If the recording time is about 30 seconds longer, the message would expect to be displayed. I spend my days longing for Pocket SDR.

Use of QZS L6 Tool with own observation equipment

Use the TCP packet observation tool nc and the command line application str2str of the open source positioning tool RTKLIB to observe L6 messages and RTCM messages in real time with the QZS L6 Tool.

For example, suppose the Allystar HD9310 Option C receiver is set up for remote observation by str2str. I have this receiver connected to my Raspberry Pi. For example, make the HD9310 Option C receiver available over TCP port 2000 as follows:

str2str -in serial://ttyCLAS:115200 -out tcpsvr://:2000

Let’s display the data observed by this remote device. For example, the observation for the device with IP address 192.168.0.1 and port number 2000 is performed as follows.

nc 192.168.0.1 2000 | ./alst2qzsl6.py
nc 192.168.0.1 2000 | ./alst2qzsl6.py -l | ./qzsl62rtcm.py
nc 192.168.0.1 2000 | ./alst2qzsl6.py -l | ./qzsl62rtcm.py -r | ./showrtcm.py

When we assume an NTRIP (networked transport of RTCM via Internet protocol) Caster address of ntrip.phys.info.hiroshima-cu.ac.jp, port number of 80, mount point of OEM7, we can observe the RTCM message with the RTKLIB application str2str as follows:

str2str -in ntrip://ntrip.phys.info.hiroshima-cu.ac.jp:80/OEM7 2> /dev/null | showrtcm.py
RTCM 1087 R MSM7          R02 R03 R04 R12 R13 R21 R22 R23
RTCM 1097 E MSM7          E02 E03 E05 E08 E11 E12 E24 E25
RTCM 1117 J MSM7          J02 J03 J04 J07
RTCM 1127 C MSM7          C02 C04 C06 C16 C29 C35 C39 C40 C59 C60
RTCM 1127 C MSM7          C01 C03 C10 C21 C45
RTCM 1137 I MSM7          I01 I03 I04 I05 I07 I09
RTCM 1005   Position      34.4401061 132.4147804 233.362
RTCM 1033   Ant/Rcv info  0 "JAVGRANT_G5T NONE" 0 s/n N/A rcv "NOV OEM729" ver OM7MR0800RN0000 s/n N/A

Sometimes, the CRC error message is displayed on the first boot because of the RTCM packet heading judgment in showrtcm.py. For finding the first packet, the message is read for the length of the message following the RTCM start byte \xd3, and if there is a CRC (cyclic redundancy check) error, the operation of searching for the next start byte string \xd3 is repeated. The RTCM message interpretation code in RTKLIB does not rely on the message length included in the message, but is checked by the CRC code sequentially while reading byte by byte, so it operates very stably.

If we know an NTRIP caster that outputs Allystar HD9310 option C receiver raw data and we know the mount point name, we can pipe alst2qzsl6.py -l and qzsl62rtcm.py to observe CLAS messages.

It was a little difficult for me to interpret the specification IS-QZSS-L6. The variable names are long and confusing. In fact, I’m still investigating how to use the 2-bit information of STEC Correction Availability in subtype 12 messages. To create the code, I referrd Performance Standard (PS-QZSS) and User Interface Specifications (IS-QZSS). Also, it was necessary for me to understand the contents of the explanatory material and the question and answer. References to the CLASLIB source code are useful for resolving questions in CLAS messages, but my policy is to avoid relying on CLASLIB as much as possible.

Conclusion

I was able to decode the Compact SSR message. In the next, I would like to try the real-time map display of regional information (compact network ID) included in subtypes 6, 11 and 12, the real-time display of the accuracy reduction rate DOP (dillution of precision) for each region, and high-precision positioning using your own code.

I am also interested in Galileo HAS (high accuracy service),. It seems that CSSR will be adopted for HAS.

I am looking forward to the MADOCA-PPP test radiowave broadcast that will start on September 30, 2022, and the release of the specifications of QZNMA, the signal authentication, and the test radiowave broadcast.


Related article(s):