Swift Navigation just released a major upgrade to the firmware for the Piksi Multi low cost dual frequency receiver. This should significantly improve performance since it adds support for the GLONASS L1 and L2 satellites. This is an L1/L2C only receiver so it only supports L2 on about half of the GPS satellites, those recent enough to support the new codes. On GLONASS however, there is no L2/L2C distinction and the Swift receiver supports the second frequency on all of the GLONASS satellites. There are fewer GLONASS satellites than GPS satellites but overall this change roughly doubles the measurements available to the solution. Looking at a recent six hour data set I took, the number of GPS satellites varied from 7 to 9 and the total L1 plus L2 GPS measurements varied from 11 to 14. During the same time there were only 5 to 7 GLONASS satellites but 10 to 14 total GLONASS measurements including L1 and L2.
Unfortunately, the update does not include ambiguity resolution for the GLONASS satellites within the Swift internal RTK solution. The raw GLONASS measurements are available though and RTKLIB supports GLONASS ambiguity resolution provided both receivers are identical. This means you can use GLONASS ambiguity resolution if you have two Swift receivers and are doing post-processing with RTKLIB.
I did a comparison between the Ublox M8T and the Swift Piksi Multi a few months ago and found that with only L1 GPS and partial L2 GPS, the Piksi simply did not provide enough measurements to generate a robust solution. With the new measurements available, along with other improvements they have added with the new firmware, I thought it was time to give it another test.
As I did previously, I will compare a Swift internal RTK solution to an RTKLIB post-processed PPK solution using the Swift data as well as an RTKLIB post-processed solution from a u-blox M8T L1 receiver. Swift does not provide any tools for doing post-processed solutions so the Swift internal solution will have to be real-time.
My first test was with a static rover to make evaluation of the results easier. Even though the rover was stationary, I ran all solutions in kinematic mode to get a better sense for the errors. For the rover I used a SwiftNav GPS-500 antenna mounted on my roof and connected through a signal splitter to both a Piksi Multi and a u-blox M8T receiver. For the base I used the P041 CORS/UNAVCO station which is the closest station for which I have real time access to through the UNAVCO network. It is about 17 kilometers away so a long enough baseline to be fairly challenging. I did run from early evening to late night so the ionospheric errors were not as large as they would have been at mid-day. There also happened to be about two inches of snow that fell during the measurement period, possibly affecting the result through snow accumulation on base or rover antennas? Other than the snow, this is very similar to the test I ran previously comparing a Tersus dual frequency receiver to an M8T receiver.
Let me start by giving my usual warning that these comparisons are only meant to be a snapshot of one users experience and not a comprehensive evaluation of any sort. Measurement environments vary tremendously and there is no guarantee that other people’s results will match mine.
I ran the test for approximately eight hours. Here are the rover observations for both receivers, Swift on the left, and M8T on the right. Green lines indicate dual frequency measurements and yellow are single frequency. The Swift receiver has GPS and GLONASS observations, the M8T has GPS, GLONASS, Galileo, and SBAS. Both receivers averaged roughly 25 measurements with the additional L2 measurements on the Swift roughly balancing the additional satellites on the M8T.
To more easily compare the internal Swift solutions to the RTKLIB solutions I wrote a simple matlab script that translates the csv logs written by the Swift receiver to the format of an RTKLIB .pos file, allowing me to plot both together using RTKPLOT.
When I first plotted the solutions I saw DC offsets between the Swift solution and the RTKLIB solutions. I had seen this before in my previous test. Last time I had ignored the offsets assuming they were coming from datum differences but this time wanted to pinpoint exactly where they were coming from. Usually it is easier to do these comparisons with relative measurements between the two receivers (ENU coordinates) rather than absolute solutions since the absolute solutions often involve translating between different datums. In this case though , the relative solutions were giving differences in the z axis exceeding 45 meters! I eventually traced the source of this error to different origins for the ENU coordinates between Swift and RTKLIB. Swift uses the rover as the origin and RTKLIB uses the base as origin, causing a rotation of the axis of the two ENU coordinate systems. Combined distance in three dimensions is the same either way but the distribution between axes changes significantly.
I then switched to comparing absolute solutions using LLH coordinates. I specified the same base location to both solutions using the numbers I got from the base station location file. The offsets were still there but smaller now, just a few centimeters. Eventually I realized that Swift was not using the base location I specified on the settings page but was substituting a slightly different base location generated from location messages in the incoming base RTCM stream, presumably from a different datum. I switched the RTKLIB solutions to use this base location and this eliminated the DC offsets. RTKCONV places the base location provided in the RTCM stream into the “APPROX POSITION XYZ” field in the Rinex file header, so selecting “rinexhead” option for the base station location in the config file accomplishes this.
Here are the position solutions for the first hour of the test after sorting out the offsets. On the left is a comparison of the internal Swift solution to the RTKLIB Swift solution. The yellow/green line is the internal Swift solution and the olive/blue line is the RTKLIB Swift solution. On the right is the RTKLIB M8T solution (yellow/green) and the RTKLIB Swift solution (olive/blue). The large errors are caused by the initial acquires of the RTKLIB solution (the Swift solution had already acquired when I started the data collection) and from me disconnecting the antenna twice to force a re-acquire of all solutions.
The Swift solution is re-acquiring after losing fix much more quickly than the RTKLIB solutions. In these two examples, the Swift solution re-acquired in less than one minute while the RTKLIB solutions required 5 to 10 minutes. Interestingly, the RTKLIB re-acquire times were roughly the same for the M8T or the Swift data. Presumably the Swift solution is taking advantage of linear combinations of the L1 and L2 measurements in ways that RTKLIB is not. Previously I was seeing the Swift solution sometimes take very long to re-acquire (well over ten minutes). This issue seems to be fixed and the Swift solution now seems to re-acquire quickly and reliably. So, by this metric, the Swift receiver is a clear winner, provided you are using the internal solution. For the RTKLIB solutions, the two receivers are very similar. This might be expected since they are both working with roughly the same number of raw measurements. I should mention that GLONASS ambiguity resolution was disabled in the RTKLIB solutions since the base and rover were not using identical hardware.
Next let’s compare the relative accuracy of the three solutions. I will ignore any errors that are common to all three solutions and focus on differences between the three. To do this I will use the mean of all three solutions in each axis as the “correct rover location”. I will also only use the fixed points for now, and ignore the float. First let me show the rest of the eight hours of data in which I did not disconnect the antenna at all. Again the Swift internal (green/yellow) vs Swift RTKLIB (olive/blue) solutions on the left, and M8T RTKLIB (green/yellow) vs Swift RTKLIB (olive/blue) solutions on the right.
Clearly several disruptions are common to all three solutions. Again, the Swift solution re-converges much more quickly than the RTKLIB solutions. Given that the disruptions are common to both M8T and Swift receivers, the most likely suspect is the base station. Sure enough, the base observations show simultaneous cycle slips on multiple satellites at most of the disruption points. I’m not sure what caused these anomalies but am more interested in the solution responses to them than their actual cause, as they are common to all solutions.
The mean rover position was very close for all three solutions, as were the standard deviations for each axis. It is difficult for me to interpret errors measured in degrees of latitude or longitude so I converted the LLH positions to ECEF for comparison. Here are the results, all in meters. The maximum deviation from the combined mean was 7 mm and the largest standard deviation was 1.5 cm. These errors are all small enough and similar enough that I would say the differences between them are probably not very meaningful.
Swift internal: dx=0.003 dy=0.007 dz=0.003
Swift RTKLIB: dx=-0.002 dy=-0.003 dz=-0.001
M8T RTKLIB: dx=-0.001 dy=-0.004 dz=-0.002
Swift Internal: stdx=0.006 stdy=0.013 stdz=0.010
Swift RTKLIB: stdx=0.006 stdy=0.012 stdz=0.014
M8T RTKLIB: stdx=0.005 stdy=0.012 stdz=0.015
Here are the plots of the three solutions all laid on top of each other, all relative to the combined means. All three are fairly well correlated, but in particular I find it surprising how correlated the Swift RTKLIB solution is to the M8T RTKLIB solution. They overlay on top of each other so well that it is difficult to even see the Swift solution but that is only because the M8T is on top, both had roughly the same percent of fixed points.
So in terms of accuracy, there is very little difference in any of the three solutions. However, it is clear from these plots that in relatively long baseline situations like this, the Swift internal solution will fix and re-acquire more quickly and hence would take less time to make a measurement. This difference would be smaller for shorter baselines where all solutions would fix fairly quickly and be nearly 100% fixed.
RTKLIB does have some additional flexibility over the Swift internal solution, especially in a post-processing situation which could be used to improve the RTKLIB solution, including static vs kinematic, continuous AR vs kinematic AR, and combined (forward/backward) mode instead of just forward. In this case, probably combined mode would be the most effective choice since it causes the solution to approach the anomalies in the raw data from both directions and minimize their disruption. Here is the same solution as above for the M8T RTKLIB solution (green/yellow) and the Swift RTKLIB solution (olive/blue) , but processed in combined mode. It improves both solutions significantly and brings the Swift solution to nearly 100% fix.
Overall, the new Swift firmware looks like a significant improvement over the previous version, particularly for real-time applications where time to first fix is most important and post-processing options are not available.
In my next post, I will extend the comparison to a moving rover case.