A first look at RTKLIB with dual frequency receivers

As I mentioned in my last couple of posts, I have recently been exploring the use of RTKLIB with a couple of different low-cost dual frequency receivers.  Low-cost is a relative term here.  At $600 to $1700 for the receivers, plus the cost of the antenna, these configurations are significantly more expensive than the u-blox based single frequency versions I usually work with.  Still, they are quite a bit less expensive than models from the more traditional manufacturers.

The first receiver I have is a Piksi Multi from Swift Navigation.

piksi-multi-032817

It is available from their website for $595 for the receiver board, or $1995 for a complete evaluation kit including two receivers, antennas, and radios.  This receiver relies on the new L2C codes for the second (L2) frequency and so does not support the traditional P2 codes.  L2C is an unencrypted code that is only available on the newer GPS satellites.  Roughly half the GPS satellites are currently broadcasting these codes but this number will increase as newer satellites are launched.  This does mean that the Multi can only make dual frequency measurements on the satellites that have L2C capability.  Also, although the receiver hardware is capable of supporting GLONASS G1/G2, BeiDou B1/B2, Galileo E1/E5b, QZSS L1/L2 and SBAS signals, these constellations are not supported in the current firmware.  This means that the current capability of this receiver is somewhat limited, but it should improve as they release new firmware and more satellites are launched.

The second receiver I have been evaluating is a more expensive option, the Precis-BX306 from Tersus which is available from their website for $1699.

BX306 (2)

 

This receiver does support the P2 codes on the L2 frequency and therefore is able to receive dual frequency signals from all the GPS satellites.  It also supports Glonass G1/G2 and Beidou B1/B2 in the current hardware and firmware.  Tersus also has similar receivers that are less expensive but also less capable than this one.  The Precis-BX305 fully supports GPS L1/L2 but only has support for GLONASS G1 and Beidou B1/B3.  The Precis-BX316R supports all the same constellations as the BX306 but only provides raw measurements, it has no internal RTK engine.  Both of these models sell for $999.

In the spirit of full disclosure, I should mention that Tersus gave me the BX306 receiver to evaluate and one of my consulting clients gave me permission to use their Piksi Multi receiver for this evaluation.  I appreciate both of them for their generosity.

Before digging into the details of the receivers, it’s worth first discussing what the advantages of a dual frequency receiver are over a single frequency receiver and also to what extent RTKLIB is capable of exploiting these advantages.  All of this is fairly new to me so the following analysis is based on my somewhat limited understanding.  If I get anything wrong, I am hoping one of my more experienced readers will jump in and correct me.

The most obvious advantage of the dual frequency receiver is that it provides more measurements than the single frequency receiver for the same satellite constellation.  However, if this were the only advantage, then the Piksi Multi, with GPS support only, would still be less capable than the u-blox M8T when the additional GLONASS, SBAS, and Galileo measurements are all taken into account.  Dual frequency receivers do also tend to have more high-end circuitry and tend to be paired with more expensive antennas.

The biggest advantage, though, comes from having multiple measurement of the same path through the atmosphere made with different frequencies.  Using linear combinations of these pairs of measurements in different ways we can glean information that is just not available with the single frequency measurements.  Two linear combinations that are particularly useful are the ionosphere-free combination and the wide lane combination.

The ionosphere-free combination takes advantage of the fact that the ionospheric delay is inversely proportional to the square of the frequency.  By taking the difference of the squares of the two phase measurements,  more than 99% of the ionospheric delay error can be eliminated.  The ionosphere-free combination provides the ability to deal with much longer baselines between the two receivers and also makes possible accurate PPP measurements.

The wide lane combination is simply the difference of the phase measurements made at the two frequencies and the advantage of this combination is that the effective wavelength of this measurement is a function of the difference in frequencies between the two measurements.  In the L1/L2 case, the difference in frequencies is 348 Mhz and the wavelength is 86 cms.  Resolving integer cycle ambiguities over an 86 cm cycle is significantly easier than resolving them over the much shorter L1 wavelength of 19 cm, the only option available with the single frequency receivers.  Once the wide lane ambiguities have been resolved, they can be used to assist in resolving the shorter cycle L1 and L2 ambiguities.  This can lead to much faster times to first fix with the dual frequency receivers.

Of course, these additional opportunities are only valuable if the solution algorithm takes advantage of them.  Unfortunately RTKLIB appears to be quite disappointing in this regard.  For the most part, the default configuration of RTKLIB for RTK handles the two frequency measurements independently and takes very little advantage of the linear combinations.  This makes them no more valuable than if they were two measurements from different satellites.  There is an option to enable ionosphere free combinations (pos1-ionoopt =dual-freq) in the config file which uses the ionosphere-free combinations to estimate the phase biases instead of the individual measurements.  The user manual indicates, though, that the ionosphere-free model is not applied for the RTK solution modes and I have found that setting this option when running an RTK solution breaks the ambiguity resolution.  There is also an option in the code for a wide lane ambiguity resolution but this option is not mentioned in the user manual and if set it attempts to call an external function that is not included with the RTKLIB source code.  There may be a little more support for dual frequency in the PPP solution modes.  However, the current RTKLIB version does not make any attempt at ambiguity resolution in the PPP modes.  The 2.4.2 release of RTKLIB does include what the manual describes as a beta version of ambiguity resolution but that has been removed in the 2.4.3 release.  Without ambiguity resolution, my experience with PPP solutions has been that I can get much better solutions using some of the free online PPP services that do use ambiguity resolution than I can get with RTKLIB.  I am hoping someone can prove me wrong and provide a config file that generates an RTK or PPP solution with RTKLIB that takes full advantage of the linear combinations of the dual frequency measurements but from everything I can see, there is not much code to support this capability.

Fortunately, both receivers do include the capability to calculate their own RTK solutions without RTKLIB.    So the goal in the following experiments will be to both compare the two receivers against an M8T single frequency receiver and also to compare their internal solutions to the RTKLIB solutions.  Unfortunately, neither receiver is set up to handle the post-processing of previously collected measurements and so all of the internal RTK solutions need to be done in real-time.  In my last post I described how I configured the receivers to receive real-time base station data over a cell phone link.

So, let’s start by taking a look at some actual measurement data.

Here is a set of measurement observations collected simultaneously from two receivers on a moving car.  The observations on the left are from a u-blox M8T receiver and on the right are from the Tersus receiver.  Satellites with lock to L1 only are indicated in yellow, those locked to L1 and L2 are in green.

tersus_obs

At the start of the data set, the M8T is locked to 8 GPS, 7 Glonass, 4 Galileo satellites, and 3 SBAS, for a total of 21 measurements.  The Tersus receiver is locked to 8 GPS L1, 7 GPS L2, 6 Glonass L1 and 5 Glonass L2 for a total of 26 measurements.  The greater number of satellites should give the Tersus an advantage over the M8T even before considering the extra advantages of the L1/L2 combinations or the more expensive electronics and antenna.

Here is a similar set of data.  The M8T receiver is on the left again, this time the Swift is on the right.  Again yellow is a single frequency measurement, green is for measurements at two frequencies.

 

swift_obs This time there were a few less satellites in the sky.  At the start of the data set the M8T is locked to 7 GPS, 7 Glonass, 2 Galileo, and 3 SBAS for a total of 19 measurements.  The Swift receiver has 6 GPS L1, and 4 GPS L2 for a total of only 10 measurements.  Particularly for RTKLIB which does not take advantage of the extra information in the L1/L2 combinations, it will be difficult to make up for the small number of measurements.

As mentioned before, this should improve as Swift releases firmware to support GLONASS, BeiDou, Galileo, QZSS, and SBAS, and as more GPS satellites are launched with L2C capability.

In my next post I will compare solutions generated with these different measurements, both from RTKLIB and from the internal RTK engines.

 

 

 

 

 

 

Newest U-blox M8N receivers not usable with RTKLIB

It looks like it is no longer possible to access the raw GPS measurements on the newest version of the u-blox M8N receiver.  Access to these raw measurements on the M8N has always been through debug messages not officially supported by u-blox.  Last year, when they migrated from the 2.01 version of firmware to the 3.01, version they scrambled the output of these messages so they were no longer readable by RTKLIB.

Until recently though, the units they were shipping still had an older 2.01 version of ROM.  With these units it is possible to downgrade the firmware to 2.01 using the instructions on their website.  With the older firmware loaded, the receivers revert to their previous behavior and the debug messages are no longer scrambled.

Apparently their newest units are shipping with a 3.01 version of ROM and this ROM is not compatible with the older 2.01 version of firmware.  If you attempt to load the older firmware it will appear to succeed but will still be running the newer code.

You can see what version of ROM and firmware your receiver is running using the UBX-MON-VER message from the u-center console.  The example below shows the message output for one of the newer modules with the 3.01 ROM after attempting to download the older firmware.  I believe the firmware listed under “Extension(s)” is the ROM version and the firmware listed under “Software Version” is the version of firmware loaded to flash.  In this case you can see that the ROM is version 3.01 and that the flash is still running version 3.01 even though it was attempted to load the 2.01 firmware.

fw_ver

In an older version of the M8N module, the ROM code listed under “Extension(s)” would have been 2.01 and the firmware listed under “Software Version” could be either 2.01 or 3.01 depending on how old the module was and what firmware had been downloaded to it.

There are a few more details about the issue on the u-blox forum in this thread.  Thanks to Marco for making me aware of the issue and Clive and Helge for providing a detailed explanation of what is going on.

If you are using the u-blox M8T, and not the M8N, then you will be using the officially supported raw measurement messages and would normally not care about access to the debug messages.  The only exception I know of is that the resolution of the SNR measurements are 0.2 dB in the debug messages and 1.0 in the official messages.  I have not confirmed that the debug messages on the 3.01 M8T firmware are scrambled but it is likely that they are.

[Note 6/25/17:  A couple of readers have pointed out that this is not the whole story.  It would have been more correct to say that the newest M8N modules are not usable with the publicly available versions of u-blox firmware and RTKLIB.  It turns out that u-blox did not use a particularly sophisticated method to scramble the debug messages and there are now several modified versions of u-blox firmware and RTKLIB floating around that have been hacked to unscramble the messages.  I don’t want to get into the question of ethics or legality of using these codes but just say that I personally am less comfortable using the debug messages in the modules where u-blox has made an obvious attempt to prevent this and have avoided any use of them at least for the time being.]

Zero baseline experiment

I’ve been busy with some consulting projects recently so it’s been a while since my last post but I’m finally caught up and had some time to write something.  I thought I would describe an experiment I did to both try out the “fixed” mode in RTKLIB and also provide some insight into the composition of the errors in the pseudorange and carrier phase measurements in the u-blox M8T receiver.

The “fixed” mode is an alternative to “static” or “kinematic” in which the exact rover location is specified as well as the base position and remains fixed.  The residual errors are then calculated  from the actual position rather than the measured position.  I describe it in a little more detail in this post.  It is intended to be used as a tool to characterize and analyze the residual errors in the pseudorange and carrier phase measurements.

The basic idea in this experiment was to connect two M8T receivers to a single antenna and then compare residuals between the two receivers.  I first looked at the solution using one receiver as base and the other as rover (the zero baseline case) and then compared solutions between each receiver and a local CORS reference station about 8 km away.

The M8T is typically setup to use an active antenna for which it provides power on the antenna input.  I was concerned about connecting the two antenna power feeds together, so to avoid this, I added a 47 pf capacitor in series in one of the antenna feeds to act as a DC block.  In the photo below, the capacitor is inside the metal tape wrapped around a male to male SMA adapter.  I cut the adapter in half, soldered the capacitor to each end, then wrapped it in metal tape as a shield.

zeroBL

The receivers are from CSG and each one is connected to a Next Thing CHIP single board computer, which logs the data and transmits it over wireless to my laptop.  They are very similar to the Raspberry Pi data loggers I described in a previous post, but the on-board wireless makes them more convenient to use.  At $9 each, they are also quite affordable, especially since they do not need micro SD cards like the Raspberry Pi Zeros.  They also have a built-in LiPo battery connector which can be convenient for providing power., although they can also be powered over the USB connectors.  They are also linux based, so setting them up is very similar to the instructions in my Raspberry Pi post.

I first looked at the zero baseline case where I used one receiver as base and the other as rover.  In this case the two receivers are seeing exactly the same signal from the single antenna.  Any error contributions from the satellites, atmosphere, or antenna should cancel and the only contributor to the residual errors should be from the receivers.

I collected about an hour of measurement data from my back patio.  It is next to the house and nearby trees so as usual, the data quality is only mediocre and will include both some multipath and signal attenuation.  I prefer to look at less than perfect data because that is where the challenges are, not in the perfect data sets collected in wide-open skies.

Here are the residuals for a high elevation, high signal strength GPS satellite.  Standard deviations are 0.24 meters for the pseudorange and 0.0008 meters for the carrier phase.

zeroBL1

For a lower elevation GPS satellite with low and varying signal strength, the standard deviations increased to 0.46 meters for the pseudorange and 0.0017 meters for the carrier phase.  Notice how the residuals increase as the signal strength decreases as you would expect.

 

zeroBL2

The GLONASS satellites had noticeably higher residuals.  Here is an example of a satellite with high elevation and reasonable signal strength.  The standard deviations were 1.02 meters for pseudorange and 0.0039 meters for carrier phase, more than twice the GPS residuals.

zeroBL3

I’m not quite sure how relevant it is, but the ratio between the pseudorange residuals and carrier phase residuals in each case is roughly 300, the same value I have found works best for “eratio1”, the config file input parameter that specifies the ratio between the two.

RTKLIB also estimates the standard devations of the GLONASS satellites measurements at 1.5 times the standard deviations of the GPS satellites which is less than the difference I see in the example above.

However, my numbers are for only the receiver components of the measurement errors, I’m not sure exactly which components the RTKLIB config parameters are intended to include.

For the second experiment, I calculated solutions for both receivers relative to a CORS reference station about 8 km away.  In this case, I was curious to see how close the two solutions are as they will have common satellite, atmospheric, and antenna errors but will differ in their receiver errors.  The plot below shows the residuals for a GPS satellite from each solution plotted on top of each other.  As you can see the errors are quite a bit larger than before and the correlation between the two receivers is very high.  Based on the frequency of the errors, I suspect they are dominated by multipath which will vary roughly sinusoidally as the direct path and reflected path go in and out of phase with each other.

I found it quite impressive to see how repeatable the errors are between the two solutions.  It indicates, at least at this distance, that the errors from the receiver are small compared to the other errors in the system.zeroBL4

Again, the GLONASS results were not as good as the GPS results and include a DC shift in the carrier phase that I’m not sure exactly what the cause is.

zeroBL5

I haven’t spent a lot of time trying to figure out how to best use the information in these plots but in particular I found the similarity between the two receiver solutions in the longer baseline experiment quite encouraging.  If the errors are dominated by multipath as I expect, then the baseline length isn’t that relevant and I would expect to see similar results with shorter baselines.  If that’s true, then it may be possible to derive information about the receiver’s environment from the multipath data.  People do this with more expensive dual frequency receivers to monitor things like tides and ground moisture content.  It would be interesting to see if it can be done with these low cost receivers.  Or maybe it already has been done …

 

Receiver warm-up glitches

I’ve described before the occasional glitches that both the M8N and M8T seem to be susceptible too in their first few minutes of operation, but my previous description was buried in one of my more technical posts and maybe not seen by people more interested in just the practical side of using RTKLIB, so I thought it was worth bringing them up again.

Here is an example of one of these glitches which was in a data set recently sent to me by a reader, and one that was giving him trouble finding a solution.  The data is very clean, except for a nearly simultaneous cycle-slip (shown by red ticks) on every satellite.

rec_glitch

Here is a zoomed in image of the same glitch.

rec_glitch2

I see these glitches on both the M8N and the M8T receivers.  Every occurrence I have seen, the glitch occurred within a few minutes of turning on the receiver, and was present on every satellite.  In this example it occurred seven minutes after starting up, usually I see it within in the first five minutes.

These glitches are very disruptive to the RTKLIB solution.  Since the cycle-slips affect every satellite, all the phase-bias kalman filter states are reset and the solution has to start again from the beginning.  In some cases, the phase-biases initial values may have larger than normal errors in which case it is even worse than starting over.

I don’t have any good suggestions on how to deal with these other than to avoid them in the first place.  From my experience I believe they are more likely to occur if the external environment of the receiver has just changed.  For example if it went from hot to cold, or into the sun.  Once the receiver has had time to stabilize, everything is usually OK.

Giving the receiver time to adapt to it’s current environment before collecting data and protecting the receiver from sudden changes should help avoid these glitches.  Using external antennas with cables rather than the small antennas that come with the receivers helps because it allows you to place the receiver in a more protected location than the antenna.  For example, when I collect data from a moving car, I place the antenna on the roof but keep the receiver in the car.

For information on plotting the observations with cycle slip enabled see this post.  For another post where I discuss this problem in more detail, see this post.

Does anyone else have more information on what causes these glitches and maybe other steps that can be taken to avoid or deal with them?

 

 

Counterfeit M8N modules

I had a few  comments recently on counterfeit u-blox M8N modules so I thought I would take a closer look at some of my receivers to see if I could spot any fakes.

Here is a photo of the module label for a unit from CSG, the most expensive M8N receiver I have and based on their reputation, the one I have the most faith that it is genuine.

csg_ubx

 

Here are photos from two of my other receivers.  The on on top is from a GYGPSV5-NEO I got from ebay.  As far as I can tell this one is genuine as well since the label looks very similar.  Performance-wise, it is also indistinguishable from the CSG unit.

real_ubxfake_ubx

The photo on the bottom is a from a very inexpensive M8N based receiver I bought recently on ebay but have not used.  They didn’t even try very hard to make it look real!  The font is different, the QR code is different, the copyright symbol is a completely different size.    I don’t think there is any question that this is a fake.  I have not used this module so I don’t know how well it performs compared to the genuine modules.  It’s possible it works just as well, I don’t know.  I also didn’t take off the module cover and look inside but I would assume it has a real ublox M8030 chip inside.  Apparently some of the fake units cut corners on some of the other components inside such as the size of the flash.  Here’s a photo of the unopened unit.

neom8n_dg

 

I did open up one of my GYGPSV5-NEO receivers that I had accidentally damaged by using 5 volts on the UART lines instead of 3.3 volts.  This is what it looked like, in case anybody is curious.

inside_ubx

 

On another note, I have just updated the demo5 executables on my website.  The new code is merged up to RTKLIB 2.4.3 b26 and now matches what I have on my Github page.  It includes the changes I described in my last post as well as a change for post-processing “combined mode” that I will describe in a future post.

New website

My previous post is actually part of a new website I am in the process of building to eventually replace this blog.  It’s been nearly a year since I started this blog and while it has been a good experience, I am starting to feel the blog format can be somewhat limiting.  A website should make it easier to organize and maintain the existing information and also allows for  better upload and download capabilities for code and data.   It will be intended more as a general resource and less of a description of my own personal experiences but I will also continue to post what I’m up doing to my blog, either as part of the website, or link to it from there.   I haven’t figured out exactly how to integrate the two yet.

However, the most important reason I’m making the change is to try and migrate to a much more user-interactive experience.  A place where every reader can have their own page and can describe what they are doing and communicate with others rather than just read about what I am doing.  The only similar forum with high activity that specializes in low-cost precision GPS that I am aware of is the Emlid forum, and while it is very good, it is obviously intended just for users of their products.  I’d like to create something somewhat similar, but to serve a broader audience to include any hardware, software, or application related to low-cost precision GPS.  I want to find out what everyone else is doing with RTKLIB.

The website is not quite ready for prime time but it is getting close.  If you’d like to check it out you can go to rtkexplorer.com and let me know if you have any ideas or suggestions to improve it.  I took the “lib” out of the name partially to make it easier to remember but also to broaden the potential scope beyond RTKLIB.

 

Selecting a GPS receiver (M8N vs M8T)

[Update 6/7/17: The newest version of the M8N is no longer usable with RTKLIB.  See this post for details]

[This is an updated version of my very first post with more info about the differences between the M8N and M8T]

Selecting a GPS receiver

The first thing you will need to begin your journey into low-cost precision GPS is a receiver that provides access to the raw GPS position signals;  pseudorange and carrier phase.  There are only a few low cost GPS chips that provide these signals.  I chose the u-blox receivers because they seem to be the most available and lowest cost option out there.  Also I was able to find examples of other people successfully using them with RTKLIB, including Tomoji Takasu, the author of RTKLIB (see here).

The NEO-M8 series is the latest generation from Ublox.  There are three basic versions of the chip, the NEO-M8N,  the NEO-M8T, and the NEO-M8P.  The NEO-M8P uses u-blox’s own integerated RTK (real-time kinematics) solution and is significantly more expensive than the other two.  I have not worked with this version and don’t know anything about it.  Assuming you plan to use the RTKLIB open-source software to process the raw GPS signals, then you will want to choose between the M8T and the M8N.

NEO-M8T

The NEO-M8T is more capable and more expensive than the NEO-M8N.  Unlike the M8N, it is specifically intended to be used for precision positioning and officially supports output of the raw signals.  The current firmware supports the GPS and GLONASS satellite systems and newer firmware should be available soon to also support the Galileo system.

The best source for a M8T based receiver that I am aware of is from CSG Shop for $75.  It has a USB interface which means it can easily be connected directly to a computer without any kind of adapter.  It does not come with an antenna but CSG also sells a u-blox antenna for an additional $20.  I have had good results with this antenna and would recommend it.  Assuming you buy two units, one for a base and one for a rover, this setup will cost just over $200 with shipping.  If you are looking for maximum performance and easy setup, and the $200 is within your budget, I would recommend this choice over the M8N.  Here’s a photo of the receiver and antenna from CSG.

UBLOX NEO-M8N GPS GNSS receiver board with SMA for UAV, Robotsantenna

Another M8T-based option, if you are looking for a more integrated solution and willing to spend a little more is the  Emlid Reach.  This is a pair of M8T receivers combined with Intel Edison SBCs with wireless and bluetooth as well as higher quality Tallysman antennas for $570 for the pair.  It uses RTKLIB for the GPS solutions but also includes an additional layer of code to make setup and use easier for the average user.

NEO-M8N

If you’d prefer a less expensive choice than the M8T and are willing to accept a few compromises then you should consider the M8N.  The NEO-M8N chip does not officially support output of the raw GPS signals but can be configured to do so with undocumented and unsupported commands over the serial port.  These commands are no longer available in the latest firmware (3.01).  However most units shipping today still have the older 2.01 firmware and so still work.  Also, the firmware can be downgraded from 3.01 to 2.01 if you did end up with a receiver with the newer firmware.  [Update 6/7/17: This is no longer true if the M8N comes with ROM version 3.01] The older firmware does not support Galileo.  Going forward, as that system becomes more capable,  this will become a more significant disadvantage of the M8N receiver.

Performance-wise, the M8N and M8T are based on the same core and for the most part are very similar.  There is one noticeable difference however in the way the M8N processes the GLONASS measurements.  Without getting into too many of the details, the issue is that normally when using two identical receivers, the GLONASS satellites can be used to solve the integer ambiguities, but with the M8N this is generally not true because of some additional error terms.  I have added a partial fix to my public branch of RTKLIB to calibrate out these errors after first fix.  If you are using the standard 2.4.3 version of RTKLIB, though, you will not have this capability, and either way you will not have this for the initial acquisition which means it will take a little longer with the M8N to get a good fix.

Most of the inexpensive M8N receivers are intended for use in drones and use a UART interface rather a USB interface.  This means you will need an FTDI type adapter to translate UART to USB and most likely will need to solder a few wires to get this hooked up.  You will find many choices available online for $15 to $40 per receiver including shipping.  These usually include an inexpensive, lower-performance antenna.  You will have to add $5-$15 for the FTDI adapter.  Still, you should be able to put together a pair of receivers fairly easily for under $75, less than half the cost of using the M8Ts.  If you are willing to wait for parts from China, you could do it for less than $50 for the pair.  Although not quite as capable as the M8Ts, if you are careful to collect good quality data and include a little more time for initial acquire, much of the time the results will be indistinguishable between the M8N and the M8T.

I have experience with three different M8N based receivers and have gotten good results with all three.  The first was from CSG Shop and while a perfectly good receiver I would not recommend it because the price is only ten dollars less than the M8T so if you are going to go that route, get the M8T.

The second receiver I have used is intended for drones and is marked as a GY-GPSV3-NEOM8N.  It is available from several suppliers, I bought it on Ebay for $25.78 including antenna and shipping.

The third type of receiver I have used is very similar but includes an on-board magnetometer.  It is labeled as GY-GPSV5-NEOM8N and sells for about $5 more than the GY-GPSV3-NEOM8N and is also available from multiple sources.  The magnetometer can be useful for collecting additional information about heading and orientation but I have not used it much yet.

Here’s a couple of other M8N receivers worth considering.  I have ordered both of them but have not had time to evaluate them yet.  For the very lowest cost and with an integrated receiver/antenna package, the unit on the left from ebay, shipped from China is  $16.65 including shipping.   The Reyax RY835AI unit on the right includes an accelerometer, gyroscope, and magnetometer with onboard antenna, all for $18.99 from Amazon Prime  (thanks to Ken McGuire for this suggestion).

[Update 12/6/16:  I have not tested the unit on the left yet but have verified the M8N module is counterfeit based on inconsistencies between the labels on this module and my other modules.  Preliminary testing of the Reyax unit was disappointing for me with low satellite count and low SNRs.  I suspect it may be because the antenna is passive unlike my other receivers that all have active antennas, but Ken has shown data with his receiver that looks much better so I’m not sure why the differences.  He has extended the ground plane on his unit but that doesn’t usually have a large enough effect to explain the differences I see.]

 

neom8n_dg 81yneho8uxl-_sl1500_

 

In summary, I would recommend the M8T receiver with a u-blox antenna for someone that has a specific application in mind and is looking for maximum performance and ease of setup.  However, the M8N with included antennas is how I got started and I still think it is a good choice for anyone that just wants to explore the capability of precision GPS without spending a lot of money.  It could also be a good choice for someone planning on building multiple units for a more price-sensitive application and is willing to work within it’s constraints.   Combining the M8N with a u-blox or other external antenna is another possibility that will put you somewhere in the middle for both capability and cost.