Getting started with RTKNAVI

[Update 11/25/16:  See here for a more recent version of this post]

Up until now I have used RTKLIB entirely for post-processing previously collected data and have not tried to process any data real-time. Now that RTKNAVI, the real-time GUI version of RTKLIB, is successfully compiling in the 2.4.3 b17 release of RTKLIB, I decided to give it a try.

I first had to update the GUIs to add all of my additional input configuration parameters and options. I started a new “Demo5” branch in my Github repository with these changes. While I was at it, I also updated the RTKPOST GUI for post-processing so both applications now support all of what was available previously in my code only in the RNX2RTKP CUI version. I’ve uploaded the executables and they are available here along with all the input configuration file and receiver startup files I used for this exercise.

As a starting point I chose to connect both M8N receivers directly to my laptop PC. This is not a very useful configuration, since the rover can only travel as far as the USB cable extends, but it greatly simplifies things, avoiding have to deal with radios or other real-time links while getting started. I connected both receivers to my laptop USB ports using FTDI boards to translate from UART to USB as I’ve previously described in this post. We’ll connect a pair of  3DR 915 Mhz radios later to make this a useful setup.

Below I will describe how I set up and ran RTKNAVI in the hope it will be useful to other people just starting out. I will assume you are using M8N receivers and my version of the code but much of this will also apply to the most recent 2.4.3 release version of code and to other receiver types as well.

When you first bring up RTKNAVI it should look something like this:

rtknavi1

In the top left corner you will see what version of code you are running. If you are running my code, you should see the demo4 (I need to update this to demo5) tag. In the top right corner are the menus for setting up the input, output, and log streams. We will start here.

Click on the “I” button to bring up the “Input Stream” menu. The red ovals below show what we need to change here. Check the boxes for both the rover and the base station, set both Types to “Serial” and the “Format” for both to “u-blox”. Plug the rover receiver USB cable into the laptop, then click the “Opt” button for the rover to bring up the “Serial Options” menu. Click on the arrow next to the “Port” box and select the com port for the rover. It should be the only choice at this point. Set the baud rate to match the GPS receiver, then click on OK. Plug in the USB cable for the base station receiver and then click the “Opt” button for the “Base Station”. Set the “Port” and baud rate as you did for the rover.

rtknavi2

Next, click the “Cmd” button for the rover to specify the commands that RTKNAVI will use to initialize the GPS receiver. Click the “Load” button in the “Serial/TCP Commands” pop-up and select the “m8n_rover_5hz.cmd” file. (You should have downloaded this when you downloaded the executables). Do the same for the base, but choose the “m8n_base_1hz.cmd” file. These files will configure the rover to output raw GPS, GLONASS, and SBAS measurements at 5 Hz, and the base station at 1 Hz. We run the base station at a lower sample rate since it is not moving and later we will need to relay this information over a real-time link which may have limited bandwidth. Check both boxes to enable the “Commands at startup” and the “Commands at shutdown”, then click OK to close the two windows. If you are not using the M8N receivers you will need to provide your own startup files.

rtknavi3

Next we’ll configure the output stream to send the solution to a file. Click the “O” button to open the “Output Streams” pop-up. Check the box next to “Solution 1” to enable the ouput stream, set the “Type” to “File” and the “Format” to “E/N/U-Baseline”. This will format the output to give us the distance between rover and base. Enter a file name and path in the “Output File Path” box.

rtknavi4

Next we will set up the log files. Although these are not necessary to run RTKNAVI, they are very useful for debugging any issues that may come up later. Check the boxes for both “Rover” and “Base Station”, and set both “Types” to “File”. Enter file names for both logs. They will be in raw ublox format so I give them a “.ubx” extension. If you check the “Time-Tag” box, you will be able to re-run the log files with RTKNAVI. If you don’t check this box, you can still re-run the logs, but only with one of the post-processing apps (RTKPOST or RNX2RTKP)

rtknavi5

OK, that should take care of all of the data streams. Next we will set up the solution configuration options. Click on the “Options” button in the bottom row of buttons. Select the “rtknavi_5hz_m8n.conf” file as shown below.

rtknavi6

Again, you should have downloaded this file with the demo5 executables. We’ll go over the details of these settings in this file later, for now I’ll just mention that the solution mode is set to “Static-start”. This option is only available in the demo5 code and will assume the rover’s location is stationary (“Static” mode) until a fixed solution is achieved, at which point it will assume the rover is moving (“Kinematic” mode). In this exercise we could use “Static” mode instead of “Static-start” if we didn’t plan to move the rover, or “Kinematic” mode if we did.

There is no need to enter the base station location if we are only concerned with relative distance between the rovers which is what we are doing in this exercise.  The configuration file specifies that we will use the measured “Single” position for the base station location.  I have limited the number of averages for the base station location to one because allowing the base to move while we are running the solution can cause it to converge quite slowly.  If you were trying to calculate absolute position with any accuracy you would need to enter accurate coordinates of the base station in the position sub-menu.

At this point, before we setup all the output windows, it would be a good time to verify the receivers are communicating properly with the laptop. I suggest using the ublox evaluation software, u-center, to do this. Open u-center, connect to each receiver, check it’s baud rate is correct and monitor the packet output window for a few seconds. You should see readable NMEA text messages if everything is working right for each receiver. You can read this post for more details on using u-center. If you need to change a baud rate, don’t forget to save the configuration to the receiver so it will come up correctly after a power-cycle. Also don’t forget to disconnect u-center from both receivers, or close it when you are done or it will prevent access to the com ports when you start RTKNAVI.

Coming back to RTKNAVI, the last thing to set up the output windows. Clicking on the two arrows in the top right corner will cycle through various options for the main display window. The right arrow cycles through plot types and the left arrow through sub-types. I’ve chosen “Rover:Base SYS SNR (db Hz)” here which allows us to see signal strengths for all satellites for both rover and base. Satellites are colored by system (GPS, GLONASS, SBAS) and only satellites with sufficient quality in both receivers to be used in the solution are colored, the others are grayed out. Clicking on the small box above the “Start” button brings up additional monitor windows. Each window allows you to choose what that window will monitor. For this exercise, we will click the box three times to open three windows and set them to “RTK”,“Obs Data”,and “Error/Warning”. You can re-size and move around the windows to make all of them visible at the same time as I have done in the screen capture below.  The  example below shows what the screen looks like after hitting start, at the moment your boxes should be mostly empty.

rtknavi7

Once you’ve done this, we are almost ready for the big moment! First check your antennas, make sure both have open views of the sky with no nearby obstructions and you have ground planes under both antennas. If all looks good, go ahead and click the “Start” button in RTKNAVI.  The monitor windows should start to fill with information and hopefully look something like the example above. In this case, the GPS receivers should have had enough time to converge to an internal solution while we were verifying them above and before we pushed “Start”, but if you skipped that step let the receivers run for a minute or two after power-up before clicking the “Start” button.

OK, now let’s check a few things to make sure everything is working right. First look at the main display window, shown in the upper left corner above. If you are in North America you should see colored bars for both receivers for all three systems (GPS, GLONASS, and SBAS). In Europe the SBAS satellites will be grayed out since the EGNOS SBAS satellites don’t broadcast range information.

Next check the observation monitor window, shown on the far right above. You should see valid pseudorange (P1) and carrier-phase (L1) measurements for both receivers (1 and 2). You should see both GPS (Gxx) and GLONASS (Rxx) and possibly SBAS (Ixx) in the list, again for both receivers. The rover observations should update five times per second and the base observations one time per second. If they are not continuously changing, something is wrong with your setup.

Next, check the Error/Warning monitor window shown on the bottom left above. In the first couple minutes you will see “large residual” errors and “position variance too large” errors and maybe a few “slip detected” errors as the solution converges. This should switch to mostly “ambiguity validation failed” errors as the solution converges but before the ambiguities are resolved. If you are getting frequent occurrence of any other message, then something is probably wrong and needs to be investigated. If not, the ambiguity resolution ratio (AR ratio) listed in the main display window and in the Error/Warning messages will fluctuate up and down but eventually should reach 3.0 at which point the solution status in the main window should switch from “Float” to “Fixed” and hopefully stay there. For me, this typically occurs in less than 5 minutes but this number will vary depending on your configuration. At that point the “Positioning mode” in the RTK window should switch from “Static-start” to “Kinematic” and now if you like you should be able to move the rover antenna without losing lock.  Make sure you don’t block the antenna’s view of the sky when moving it.  Of course the movement will have to be pretty limited since both receivers are hard-wired to the laptop.  (Note: while writing this tutorial I noticed that the RTK window is incorrectly displaying“Moving-base” instead of “Static-start” before the switch over. This is a bug I must have created when I added the “Static-start” mode but it only affects the display window and not any functionality. I’ll plan on fixing this in my next code update)

Assuming you’ve got a fix, then I would suggest playing around with all the display options since there are many of them. Below I show a screen capture after achieving a fix. I’ve switched the main display over to baseline so it shows the distance between the two antennas. I’ve also clicked the “Plot” button to start real-time plotting of the solution and let it run for 5 or 10 minutes. You can see the solution is moving around by at least a couple of centimeters. If I had run the solution as “Static” instead of “Static-start” this variation would be much smaller but I would not be able to move the rover around.  I also suspect if I had waited a few more minutes before collecting this data, the errors would be smaller.

rtknavi8

Hopefully everything goes well and you quickly get an accurate fix. If you don’t get a fix, I would first check the error/warning window, see if there are any clues there. If not, and all the other checks I mentioned above look good, then the next step would be to look at the log files we enabled in the data stream menus. They will be in raw ublox format but can easily be converted to RINEX observation and navigation files with the RTKCONV GUI. Plot the observation files using RTKPLOT and look for cycle-slip issues or other quality problems with the measurements. Check that there are no missing or extra observations. If they look good, the next step would be to post-process the log files with RTKPOST to see if that makes a difference. If all that looks good and you still can’t get a fix, send me a copy of the raw data files and I’ll take a look.

Good luck!!

In the next post I will add the radios to make this a more useful experiment.

Advertisements

RTKLIB: Demo 4 vs 2.4.3 B16 code

Over the last six months or so I have made a number of changes to the RTKLIB code. A couple of these (ArlockCnt bug and M8N half-cycle bit) have made it back into the officially released code on Github but most of them have not. While I was in the mode of comparing solutions, I thought it would be worthwhile comparing solutions from the latest demo4 code from my Github repository to the latest released code (2.4.3 B16) to see how much they differ. The demo4 code is based on the 2.4.3 B12 released code but I do not believe the differences between releases B12 and B16 should affect this comparison.

I used the same data sets and input configuration files I used for the M8T vs M8N comparisons I described in the last few posts. The only differences being that I removed the options and input parameters that do not exist in the released version from the configuration files for the released code runs.

Here are the solutions from the previous post for both the pair of M8N receivers and the pair of M8T receivers using the latest demo4 code.

     M8N                                                                             Reach M8Trelease1

Here are the solutions for the same data sets using the 2.4.3 B16 code, both RTKCONV and RNX2RTKP.

     M8N                                                                             Reach M8Trelease2

A quick look at the vertical scales as well as the shape of the plots shows that the M8N solution is completely invalid whereas the M8T solution looks reasonably close although with a noticeably lower fix ratio. The difference between the M8N and the M8T is much greater with the release code than it was with the demo4 code. This is consistent with observations from other users that the M8T is significantly better than the M8N, something I did not really see in the demo4 solutions.

Let’s also look at the differences between solutions since they can indicate errors. Here is the difference between the demo4 M8N and M8T solutions from the previous post. Remember that this difference should be a circle with a radius equal to the distance between the rover antennas since the data is from two different receivers mounted on the same rover. I have only plotted data for the fixed points since those are the ones we have highest confidence in.

release3

There is no point in looking at the release M8N solution since it is so poor, but we can compare the M8T solutions from the two code versions. In this case, because we are using two solutions from the same data set, the difference should be zero. Here is a plot of the difference between those two solutions for the M8T data set, again only for the fixed solution points.

release4

Here is the same data, plotted by axis.

release5

The differences are quite large, up to nearly a meter in x and y, and more in the z axis. Based on the previous comparison between the M8N and the M8T with the demo4 code, I have fairly high confidence in the demo4 solution so I suspect the errors are in the release solution. We can verify this though by looking for discontinuities in the solutions at the erroneous points.

Let’s pick the point at 01:22:47 which shows a large difference between solutions in all 3 axes. Here are the two solutions zoomed into this point in time.

Reach M8T: demo4                                Reach M8T: 2.4.3 B16release6

Notice the large jump in the released code solution. Since this data is from a car driving on roads, the large discontinuities in the y and z axes are not real and confirm the error is in the release code and not the demo4 code.

So, several people now have asked if these changes will make it into the official code. As I’ve mentioned before in one of my comments, I’ve chosen not to submit all of my code changes to the official code repository. This is because my changes are focused on one small corner of the world of GPS (low cost) and tested on an even smaller corner (low-cost Ublox) and I am not sure how well they all will translate into the larger realm that RTKLIB supports. At minimum, it seems they would require a fair bit of testing on multiple hardware platforms which I don’t have the time or resources to do. I’m also not sure some of them would all be considered sufficiently mathematically rigorous for general widespread use. But I will continue to make them available in my Github repository for anyone that would like to incorporate them into their code.

I have just submitted my most recent change, the improvement in decoding cycle-slips from the M8T raw data, as an issue to the official Github repository.

 

Update 8/28/16:  I now have a demo5 version of this code in which I have made the GUI versions (RTKNAVI and RTKPOST) fully functional with all of the demo4 features.  The code is in a new demo5 branch in my Github repository and the executables are here

Ublox M8N vs M8T: Part 3

 

This is the third part in a series of posts comparing data from a pair of Ublox M8T receivers with data from a pair of Ublox M8N receivers. In the first post I identified a problem with erroneous fixes in the RTKLIB solution for the M8T data. In the second post I found that the source of the problem appeared to be in the handling of cycle slips in the translation from the receiver binary output to the text input used by RTKLIB. I also showed that adopting an algorithm more similar to the one used to translate the M8N binary improved but did not entirely fix the problem. In this post I will show that if the cycle slip translation is more precisely adapted to the differences in binary output between the M8N and the M8T then we can virtually eliminate the erroneous fixes and get an M8T solution that is now slightly more accurate than the M8N solution.

One thing I may not have made clear in the previous posts is the way I am collecting and processing the data from the Emlid Reach M8T receivers. I am using their ReachView software to collect the raw GPS data but all the processing is done afterwards using my own demo4 version of RTKLIB. I don’t have access to Emlid’s RTKLIB source code and don’t know if they have made any changes that might have improved this issue in their own real-time version of RTKLIB. So this is more a comparison between the M8N and the M8T receivers using my version of RTKLIB and not an evaluation of anything specific to the RTKLIB version of Reach.

Last post I finished with this plot showing the difference between the M8N solution and the M8T. For reasons I’ve explained before, we know this should be a perfect circle with a radius equal to the distance between the receivers.

walker12

By looking at spikes in the z-axis accelerations we were able to show that the deviations from the circle in the above plot were due to errors in the M8T solution and not the M8N solution. This plot was taken after I had modified the binary to text translation in RTKCONV to make the M8T translation more similar to the M8N translation. Before that, the errors were much larger.

Let’s start by taking a closer look at the binary outputs of the two receivers. The details for the M8T are available in the M8 receiver spec and for the M8N in this document from Tomoji Takasu but I will summarize them here.

Both receivers provide three values for each satellite output sample that can be used to evaluate the quality of the carrier phase measurement. The first is the carrier-phase valid bit. Both receivers provide this in the tracking status byte. It indicates that the receiver is currently locked to the carrier-phase for this satellite. Note that it does not tell us if the receiver has been continuously locked since the previous output sample and it also does not indicate anything about the quality of the measurement.

The second output (locktime or lock2) indicates how long the receiver has been locked to the carrier-phase for this satellite. If this count is lower than the count for the previous sample, then an unlock, i.e. cycle-slip, has occurred. Both receivers also provide this value, and this is what RTKCONV uses to detect a cycle-slip.

The third value (mesQI or cpStdev) is a quality indicator and this is where the receivers differ. On the M8N this appears to be more of a state indicator than a true quality indicator. The comments indicate that it’s value corresponds to:

0:idle
1:search
2:acquired
4-7:lock

For the M8N, the RTKCONV code throws out any phase measurement for which this quality indicator is not between 4 and 7.

On the M8T, the quality indicator is actually a numeric estimate of the standard deviation of the carrier phase measurement. If the value is between 1 and 7, then the estimate of standard deviation is this value multiplied by 0.004 meters. If this value is 15, then there is no valid estimate. This value is currently ignored by the RTKCONV code and that is the root of the problem.

Before discussing how to modify the code to incorporate this information, we need to understand exactly how the cycle-slip bit is interpreted by RTKLIB. On a sample for which this bit is set, RTKLIB will reset the phase-bias state for that satellite based on that carrier-phase measurement. Note that the reset is done using the measurement from the current sample, not the following sample. What this means is that the cycle-slip bit should not be used to indicate that there is a cycle-slip on the current sample. Rather it should indicate that there has been a cycle-slip since the last good measurement and that the quality of the current sample is now high enough to use it to reset the phase-bias state.

So how high should the quality indicator be before resetting the phase-bias? It will be a trade-off between time and accuracy. I chose the value of four since it’s in the middle of the scale and somewhat equivalent to what is used on the M8N, but it could be argued that this value should be higher or lower. Forcing the cycle-slip to be set on a good sample also eliminated the problem we previously saw with samples subsequent to the cycle-slip not being flagged, so I was able to remove the code I added in the previous post.

Here are the changes I made to the original code for the M8T receiver. The new variable cpstd is the standard deviation of the carrier phase measurement as described above. The constant STD_SLIP is the quality threshold described above and is set to 4.

walker13

Here is the position solution calculated with the above code change.

walker14

Here is the difference in position between the two solutions. As you can see, the deviations from the circle have been significantly reduced.

walker15

The noise in the z-axis accelerations has also been significantly reduced and is now slightly lower than in the M8N data.

       M8N                                                                           Reach M8Twalker16

I have posted the raw data and config files to my data set library in the niwot2_car folder and the code changes to my Github page.