Galileo operational again

In my previous post I wrote about the outage of the Galileo EU satellite navigation constellation that started on 2019-07-12 01:50 GST. For several days, all the Galileo satellites kept transmitting the same batch of ephemeris, which corresponded to 2019-07-11 21:50 GST, rather than sending updated batches of ephemeris.

This situation continued until around 2019-07-16 19:00, when several people reported that they were receiving updated ephemeris from some Galileo satellites. These ephemeris could be used for navigation correctly. The NAVSAS group from University of Torino has published a post where they show, for each satellite, when the updated ephemeris were first received by their equipment in Torino, Italy.

The restoration of the system was publicly announced with NAGU 2019027, published on 2019-07-18 08:20. This NAGU stated that starting from 2019-07-17 20:52 the service was restored, but users might experience some instability.

It is interesting to look at the MGEX broadcast ephemeris to see what happened between 2019-07-16 19:00, when users started to see updated ephemeris, and 2019-07-18, when the system was considered to be fully restored. In this post, I do a detailed analysis of the broadcast ephemeris.

I will use the IGS BRDC files, which are multiconstellation navigation RINEX files obtained by merging navigation RINEX files generated by receivers throughout the world. The advantage of using merged RINEX files rather than a single station as the NAVSAS group did is having a global view of the whole constellation. A single station can only monitor the satellites that it has in view.

The tool I have used to process navigation RINEX files is georinex. This is a Python library that allows one to load observation or navigation RINEX files as an xarray Dataset. This makes it easy to process all the information in the file and represent it graphically.

In doing this, I have found two difficulties. The first is that when georinex loads a navigation RINEX file, it ignores entries which have a duplicated SVN and timestamp. This is done because, without filtering out duplicates, the xarray Dataset that georinex generates would have duplicated coordinate labels, and many features of xarray do not work well with these duplicated labels. Often, RINEX entries with duplicated SVN and timestamp will have exactly the same data, so nothing is lost by filtering out the duplicates.

However, in the case of Galileo, the different I/NAV and F/NAV pages give rise to duplicated entries which do not have the same data. As shown in page A25 of the RINEX 3.03 format description, these are distinguished by the value of the data sources field. This field has the following possible values:

  • 0x201, which means that the data comes from E1B I/NAV, the clock data and SISA refer to the E5b,E1 signal pair and only the DVS and HS bits for E5b and E1 are valid.
  • 0x102, which means that the data comes from E5aI F/NAV and the clock data and SISA refer to the E5a,E1 signal pair and only the DVS and HS bits for E5b are valid.
  • 0x204, which means that the data comes from E5bI I/NAV, the clock data and SISA refer to the E5b,E1 signal pair and only the DVS and HS bits for E5b and E1 are valid.
  • 0x205, which means that the data is merged from E5bI I/NAV and E1B I/NAV, the clock data and SISA refer to the E5b,E1 signal pair and only the DVS and HS bits for E5b and E1 are valid.

It is expected that entries with data source values of 0x201, 0x204 and 0x205 will contain the same data, since the I/NAV pages in E5bI and E1B should transmit exactly the same information. However, if one is interested in looking at the DVS and HS bits of all the signals, it is necessary to collect entries with a data source value of 0x102 and at least one of 0x201, 0x204, 0x205.

Since there is no way to collect all this information with georinex, I have made a modification that doesn’t filter duplicated entries. Instead, if a duplicated entry is found, it is stored under a different SVN, identified with a postfix. In this way, if we consider the satellite E01, the data is stored using the SVNs E01, E01_1, E01_2, etc., as additional duplicated entries are found.

The modified version of georinex can be found in the rinexnav_nonunique branch of my georinex Github fork.

The second difficulty I have found is that several entries in the IGS BRDC files have the SISA and SV health fields swapped. The is probably caused by some buggy receiver that generates incorrect RINEX files. I have come up with some heuristics to detect when these fields are swapped and revert the swap. This is done if the SV health field is not an integer number or is -1, since these values are not acceptable for the SV health field, but are acceptable for the SISA field.

I have made a Jupyter notebook that loads the navigation RINEX files and represents graphically the availability of ephemeris, and the values of the SISA, DVS and HS fields. The IGS BRDC files have been fetched from the CCDIS archive.

First, I have decided to analyze the BRDC file corresponding to day 180, which is 2019-06-29. This should be an rather normal day for the Galileo constellation, with everything working nominally. Thus, day 180 is used as a control to check that my processing functions are working correctly.

The first kind of plot shows the ephemeris availability. Each RINEX entry is shown as a dot with a position corresponding to its timestamp, which is transmitted as the \(t_{0e}\) and \(t_{0c}\) inside the I/NAV and F/NAV pages, and stored in the RINEX file in date and time format.

The figure below shows a continue availability of ephemeris for most satellites, albeit with some gaps. These gaps will be studied at the end of the post. Note that E06, E10, E16, E17, E23, E28, E29, E32, E34 and E35 are not assigned yet, and E20 and E22 are not operational.

It is interesting that E24 and E31 disappear at some point. I have not found a NAGU that affects this day, so the reason for the lack of ephemeris for E24 and E31 is unknown.

The second kind of plot shows the value of the SISA (signal in space accuracy). It has a nominal value of 3.12m, which is shown in green. In the RINEX files, I have also found the values of -1, which in the navigation message is transmitted as the value NAPA (no accuracy prediction available), which indicates a potentially anomalous SIS, and 0, which according to the Galileo Open Service SIS ICD is a possible SISA value which indicates 0cm accuracy, but it is most likely caused by a buggy receiver generating an incorrect RINEX entry.

In the case of day 180, we see that all satellites broadcast a SISA of 3.12m, except for E14 (one of the excentric satellites), which broadcasts NAPA for E5a,E1 (but 3.12m for E5b,E1), and E26, which broadcasted NAPA for E5b,E1 (but not for E5a,E1) during a short period of time.

The third kind of plot shows the value of the data validity status bit for each signal. The “navigation data valid” status is shown in green and the “working without guarantee” status is shown in red. Below we see that the DVS was always OK for all satellites during day 180.

The fourth kind of plot shows the values of the health status bits for each signal. The health status has four possible values: signal OK, shown in green; signal out of service, shown in red; signal will be out of service, shown in orange; and signal component currently in test, shown in blue.

For day 180, all the satellites broadcasted HS OK for all signals, except the eccentric satellites E14 and E18, which broadcast a test status for all their signals (this is normal, since these satellites are considered to be in testing, due to their anomalous orbits). It is interesting that there are some short time intervals where it seems that E14 and E18 transmitted a HS value of OK, but probably this is caused by a buggy receiver which ignores the HS when generating the RINEX file.

Now we turn to the study of the RINEX files corresponding to the recovery of the Galileo system: days 197 and 198, which correspond to 2019-07-16 and 2019-07-17.

Below we see that most satellites start to transmit updated ephemeris around 19:00 on July 16. Other satellites follow a few hours after. The only satellite that has a noticeable delay to start transmitting updated ephemeris is E33, which started transmitting around 2019-07-17 10:00. Note that before transmitting the updated ephemeris, each satellite was still repeating the ephemeris from 2019-07-11 21:50. This doesn’t appear in the BRDC RINEX, probably because it has the incorrect date, so it is perhaps removed when merging RINEX files.

The start of the updated ephemeris can be seen in more detail in the figure below, which is a zoomed portion between 18:45 and 21:00 on July 16. A total of 15 satellites transmit the first updated batch at 18:50, with six other satellites following later.

It is interesting to think for a moment about how the ground control segment of Galileo achieved this. There are two obvious possibilities: either they commanded all the 15 satellites at once around 18:50, uploading the updated ephemeris to all of them simultaneously, or they took a few hours before 18:50 to upload the ephemeris in advance and configure the satellites to start transmitting them autonomously at 18:50. I don’t know much about the uplink capabilities of the ground segment, but the second possibility seems more likely.

Another interesting question is why E33 started transmitting the updated ephemeris much later. It happens that E33 wasn’t in view from Europe between 08:00 and 19:00 on July 16, but this also happened with other Galileo satellites, and the Galileo ground segment has uplink stations scattered over the whole world.

The next two figures show the SISA. We see that all satellites start transmitting NAPA for both signal pairs until a a few minutes before 2019-07-17 18:00, where they change to the nominal SISA value of 3.12m. The NAPA value was observed by the NAVSAS group, who also reported the change to 3.12m . E18 shows a SISA value of 0 for a short interval of time on the E5a,E1 pair. I guess that this is caused by a buggy receiver.

The figure below shows a zoom to the interval between 17:00 and 19:00 on July 17. It is clear that the SISA changes to 3.12m simultaneously on all satellites at 17:50. Maybe it is a coincidence that this happened exactly 23 hours after the first satellites started transmitting the updated ephemeris, but it seems as a well planned event. Here the explanation that all satellites were commanded in advance to change the SISA autonomously at 17:50 is the most likely.

The three figures below show the data validity status for each of the Open Service signals. We see that all satellites transmit a status of OK except for some satellites, whose first batch is sent with a status of “working without guarantee”. These are E05, E11, E12, E14, E18, E19, E31 and E33. These are precisely the satellites reported by the NAVSAS group to be transmitting a status of “working without guarantee” throughout the outage (see also my previous post). It is curious that the satellites only changed back to OK starting with the second batch of updated ephemeris. Or maybe this is just an effect of how receivers generate the RINEX, since technically the DVS fields (and also the health status) are not associated to any particular ephemeris batch identified with an \(\text{IOD}_{\text{nav}}\) and may change at any time (see Section 3.4.3 in this document), so incorporating the DVS into a RINEX file reliably is be tricky.

Finally, the three figures below show the value of the health status for each of the Open Service signals. This is as expected in the nominal case: the whole constellation broadcasted a value of OK, except for the eccentric satellites E14 and E18, which broadcasted “in test”.

There is a final topic that is convenient to address: the gaps in the ephemeris availability. As we have seen, this also happens on nominal days such as day 180 analyzed above. I have looked at this in more detail and I have found the following.

Usually, a new batch is transmitted every 10 minutes, and the \(\text{IOD}_{\text{nav}}\) value increases in one with each new batch. However, there are gaps in the BRDC files where no new batches are transmitted. These gaps are also present in the navigation RINEX files of individual stations, so I think that this is a real effect where ephemeris are sometimes not updated every 10 minutes, rather than some bug or omission in the generation of RINEX files.

An interesting thing is that, even if there are gaps, the \(\text{IOD}_{\text{nav}}\) keeps increasing at a rate of one per 10 minutes. When there is a gap, the \(\text{IOD}_{\text{nav}}\) will jump accordingly. This is best illustrated by the figure below, which shows the evolution of the \(\text{IOD}_{\text{nav}}\) for the E36 satellite on day 180. The dots correspond to entries in the BRDC RINEX.

As an example, we analyze the behaviour of the \(\text{IOD}_{\text{nav}}\) during one of the gaps in the figure above. Between 02:10 and 04:40, there are ephemeris entries for E36 in the BRDC file corresponding to the following times. Note the jump of 70 minutes between 02:50 and 04:00.

02:10, 02:20, 02:40, 02:50, 04:00, 04:10, 04:20, 04:30, 04:40

The \(\text{IOD}_{\text{nav}}\) corresponding to each of the timestamps above is shown below. Note the jump between 113 and 120, which corresponds to a jump of 70 minutes.

109, 110, 111, 112, 113, 120, 121, 122, 123, 124

I don’t know the cause of this behaviour, but I find it rather interesting.


  1. Thank you for these highly detailed technical posts. Really enjoyed following them during this unprecedented outage and tight-lipped official response.

  2. Hi,

    I’m currently seeing some similar things, with some SVs staying on older IODs for ~90 minutes. In addition, I made a graph of ephemeris age for all SVs and it similarly shows SVs getting stuck on old copies, plus then sometimes moving to a newer, but still not the newest, ephemeris. has a graph of this. Curious.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.