阅读:3791回复:9
[推荐]Writing Your Own GPS Applications: Part II
在帖子“<a href="dispbbs.asp?boardID=13;ID=38608;page=1" target="_blank" >C#, VB.NET下开发GPS程序的好东东</a>
”中,介绍了: <font>Writing Your Own GPS Applications: Part I 下面再贴出其第II部分,以供学习 (网址:http://www.codeguru.com/vb/mobile/mobileinternettoolkit/article.php/c8875__1/) </font><h4>Related Links</h4> <ul><li><a href="http://www.gpsdotnet.com/download/WritingGPSApplications2_demo.zip" target="_blank" >Download Source Code for This Article (C# ; VB.NET) - 17 Kb</a> </li><li><a href="http://www.gpsdotnet.com/download/WritingGPSApplications2_demo_gpsdotnet.zip" target="_blank" >Download GPS demo using GPS.NET - 373 Kb</a> </li><li><a href="http://www.gpsdotnet.com/download" target="_blank" >Download GPS.NET (Full SDK) - 4,756 Kb</a> </li><li><a href="http://en.wikipedia.org/wiki/Ionosphere" target="_blank" >Learn More About the Ionosphere</a> </li><li><a href="http://www.ualberta.ca/%7Enorris/gps/DOPdemo2.html" target="_blank" >Move Satellites Around With This Java Applet</a> </li></ul> <b>About the Author</b> Jon Person is the author of the award-winning "<a href="http://www.gpsdotnet.com/" target="_blank" >GPS.NET Global Positioning SDK</a>" component and has consulted for military companies and the Forest Service on GPS solutions. Jon frequently writes about GPS application development and welcomes all questions and comments at info@gpsdotnet.com. </p> <p>=======================================================</p> <p><h3>Introduction</h3> In <a href="http://www.codeguru.com/vb/mobile/pocketpc/article.php/c8079/" target="_blank" >part one</a> of this article, I described how to write an interpreter for raw GPS NMEA data. The article included source code in VB.NET which harnessed the power of GPS satellites to determine the current location, synchronize the computer clock to atomic time, and point to a satellite on a cloudy day. The interpreter also works with hand-held devices and supports international developers. Yet, the interpreter was really not suitable for commercial use because it did not monitor precision. Without precision, an application could end up making unintelligent business decisions such as accidentally telling a driver to turn left into an alley, or worse. In this second part, I'll cover precision in detail and talk about what it takes to make GPS applications smart enough for in-car navigation and reliable enough for business use.</p> |
|
|
1楼#
发布于:2005-03-11 09:30
<h3>Causes of Precision Error</h3> Thereare several phenomenon which can cause poor precision. For example,when satellite radio signals are transmitted, they are distorted by thetroposphere and especially the ionosphere. In fact, satellites very lowon the horizon are not good for getting a fix because the signalstravel through so much of the atmosphere. Some GPS devices may evenexclude these satellites from a fix to avoid the precision problemsthey would cause. <ul><img src="http://www.codeguru.com/dbfiles/get_image.php?id=8875;lbl=FIGURE23_GIF;ds=20041229">
<font size="1">Figure2-1: Satellite 1's radio signal travels through less of the atmosphere,resulting in less distortion. Satellite 2 is low on the horizon,however, resulting in significant atmospheric distortion.</font></ul> Fortunately,atmospheric distortion can be measured and corrected for the most part.This is achieved by the use of GPS ground stations, fixed locationswhich constantly measure distortions in satellite radio signals.Calculated corrections are then broadcast by radio which, when combinedwith the actual satellite signal, gives a GPS receiver the ability tocorrect distortions in real-time. <ul><img src="http://www.codeguru.com/dbfiles/get_image.php?id=8875;lbl=FIGURE24_GIF;ds=20041229"> <font size="1">Figure2-2: Distortions in radio signals are corrected by combining satellitesignals (1 and 2) with correction information transmitted via DGPSground stations (3 and 4).</font></ul> Precision errors can becompounded by slight inaccuracies in each satellite's "ephemeris."Ephemeris is a table giving the coordinates of a celestial body overtime. If the satellite's actual course deviates from its ephemeris,precision can be further diluted. This sort of error can only becorrected by firing small rockets on the satellites themselves.Adjustments are transmitted from the GPS Master Control Station atSchriever Air Force Base in Colorado Springs, Colorado. <ul><img src="http://www.codeguru.com/dbfiles/get_image.php?id=8875;lbl=FIGURE25_GIF;ds=20041229"> <font size="1">Figure 2-5: Deviations in a satellite's actual orbit path can also cause loss in precision.</font></ul> AsI covered in Part One of this article, each GPS satellite has fouron-board atomic clocks: two cesium atomic clocks and two rubidiumatomic clocks which are accurate to 1 second per 300,000 years! Still,even microfractions of a second error in these clocks can causepositional error because distance is measured at the speed of light.The Master Control Station keeps these errors at a minimum by uploadingcorrective information to satellites twice a day, every day. The last detriment to GPS precision is an effect called"multipath," which is an effect caused when a receiver receives notonly the satellite's signal, but additional signals which bounced offbuildings and other obstacles. Deflected signals take a longer path tothe receiver and are thus delayed. If they are used by the receiver,the measured distance to a satellite is overestimated, resulting ininaccurate multilateration. More advanced receivers solve multipathproblems by utilizing only the first signal detected (which is the mostdirect path from the satellite), then discarding any delayed signals. </p><ul><img src="http://www.codeguru.com/dbfiles/get_image.php?id=8875;lbl=FIGURE26_GIF;ds=20041229"> <font size="1">Figure2-3: A receiver is confused by "multipath," where several reflectedsignals are received (red) along with the direct radio signal (green).</font></ul><p> Solving all of these precision problems is done by using moresophisticated GPS receivers which use real-time correction data such asWAAS (for North America) and EGNOS (for Europe). Yet, these problemscause relatively small inaccuracies when compared with GeometricDilution of Precision, which can cause a receiver to be inaccurate bymore than an American football field. Fortunately, Geometric DOP is theeasiest to manage with the right programming techniques. </p> |
|
|
2楼#
发布于:2005-03-11 09:39
<h3>Geometric Dilution of Precision</h3> GPSdevices calculate your position using a technique called "3-Dmultilateration," which is the process of figuring out where severalspheres intersect. In the case of GPS, each sphere has a satellite atits center; the radius of the sphere is the calculated distance fromthe satellite to the GPS device. Ideally, these spheres would intersectat exactly one point, causing there to be only one possible solution tothe current location, but in reality, the intersection forms more of anoddly-shaped area. The device could be located within any point in thearea, forcing devices to choose from many possibilities. Figure 2-4shows such an area created from three satellites (using part one's$GPGSV sentence). The current location could be any point within thegray-colored area. Precision is said to be "diluted" when the areagrows larger, which leads to this article's focus: dilution ofprecision. The monitoring and control of dilution of precision (or DOPfor short) is the key to writing high-precision applications. <ul><img src="http://www.codeguru.com/dbfiles/get_image.php?id=8875;lbl=FIGURE21_GIF;ds=20041229">
<font size="1">Figure 2-4: GPS devices must choose one of several possible solutions to the current location.</font></ul> DOP values are reported in three types of measurements:horizontal, vertical, and mean. Horizontal DOP (or HDOP) measures DOPas it relates to latitude and longitude. Vertical DOP (or VDOP)measures precision as it relates to altitude. Mean DOP, also known asPosition DOP (PDOP), gives an overall rating of precision for latitude,longitude and altitude. Each DOP value is reported as a number betweenone and fifty where fifty represents very poor precision and onerepresents ideal accuracy. Table 2-1 lists what I believe to be anaccurate breakdown of DOP values. </p><ul><table border="1" cellpadding="2" cellspacing="2"><tr><th>DOP</th><th>Rating</th><th>Description</th></tr><tr><td>1</td><td>Ideal</td><td>This is the highest possible confidence level to be used for applications demanding the highest possible precision at all times.</td></tr><tr><td>2-3</td><td>Excellent</td><td>At this confidence level, positional measurements are consideredaccurate enough to meet all but the most sensitive applications.</td></tr><tr><td>4-6</td><td>Good</td><td>Represents a level that marks the minimum appropriate for makingbusiness decisions. Ppositional measurements could be used to makereliable in-route navigation suggestions to the user.</td></tr><tr><td>7-8</td><td>Moderate</td><td>Positional measurements could be used for calculations, but the fixquality could still be improved. A more open view of the sky isrecommended.</td></tr><tr><td>9-20</td><td>Fair</td><td>Represents a low confidence level. Positional measurements shouldbe discarded or used only to indicate a very rough estimate of thecurrent location.</td></tr><tr><td>21-50</td><td>Poor</td><td>At this level, measurements are inaccurate by as much as half a football field and should be discarded.</td></tr></table><font size="1">Table 2-1: Jons interpretation of dilution of precision values.</font></ul><p> Looking again at figure 2-4, three satellites created a largearea of possible solutions. This situation could be improved by twofactors: adding more satellites to the fix, and using satellites evenlydistributed throughout the sky. What would figure 2-4 look like if thesituation was improved like this? Figure 2-5 shows figure 2-4 afterthree more evenly-distributed satellites have been added. </p><ul><img src="http://www.codeguru.com/dbfiles/get_image.php?id=8875;lbl=FIGURE22_GIF;ds=20041229"> <font size="1">Figure2-5: Three more evenly-distributed satellites are added to figure 2-4,creating a high-precision environment where dilution of precision islow.</font></ul> |
|
|
3楼#
发布于:2005-03-11 09:41
<h3>Determining Precision Needs</h3> Now that the mechanics of precision have been explained, the nextstep is to figure out how to determine the actual precision needs of anapplication. As a general rule of thumb, an HDOP value of six or lessis recommended for any application which makes suggestions to the userbased on the current location. For example, in-car navigation programswhich tell the user to "turn left now" should ignore positionalmeasurements when HDOP is greater than six. But is six really goodenough? How can developers figure out which HDOP values to use fortheir own applications? To answer these kinds of questions, I like touse a simple formula: <ul><code>Accuracy of GPS Device * DOP = Maximum Allowable Error</code></ul> Thisformula uses DOP as a factor of error which, when combined with theaccuracy of the GPS device being used, yields the maximum error allowedby a level of DOP in the form of a specific, measurable distance.Another general rule of thumb is that typical consumer GPS devices arecapable of between 5-7 meters of accuracy without enhancements likeDGPS or WAAS, or an average of six meters. Using the in-car navigationHDOP of six and a typical GPS device, the maximum error allowed is <i>6m * 6 = 36 meters</i>,or 118 feet. Given that a downtown city block is roughly 475 feetsquare, the maximum allowable error is about a quarter of a city block.This is precise enough to make sure that the driver turns at thecorrect road. On the other hand, an HDOP of twelve results in anallowable error of half a city block (237 feet), which could causedrivers to turn down an alley accidentally. So, using the formula, itis possible to use an HDOP greater than six for in-car navigation, butnot by much.
The trick to using this formula is researching real-worlddistances, especially the smallest important distances. To demonstrate,take a look at golf. Does golf require more precision than in-carnavigation? A golf program needs to tell the user which golf club touse in order to make the best shot. Some research into important golfdistances finds that for most players, there is a regular distanceinterval between clubs of about 10-15 yards. Therefore, a golf programneeds no more than 10 yards (9.1 meters) of allowable error toconsistently suggest the right club. When 9.1 meters is put into theformula as <i>Maximum Allowable Error</i>, the maximum HDOP comes out to 3. So, golfing applications require about twice the precision as in-car navigation systems. <p> Why not skip theformulas and always enforce an HDOP of one? This looks like areasonable practice, but greater precision requires greater satellitevisibility. An in-car navigation system will probably not get an HDOPof one (or even three) downtown because signals are being obscured bybuildings. If the enforced HDOP is too small, the application willthrow out too many positional readings and just sit there while thedriver loses patience. Golfing applications, on the other hand, canrealistically enforce a small HDOP because they operate outdoors. Thegolfer's PDA is likely to have plenty of open sky enough to pick upseveral evenly-distributed satellites, unless their ball is in themiddle of the woods, in which case they're on their own. </p><p> To summarize, successful GPS software developers will usethe formula to determine the greatest possible DOP number. This willensure that the application minimizes the most problems due toinaccuracy while at the same time allowing the application to functionin the poorest possible satellite visibility conditions. This practicewill maximize the value and versatility of any GPS application. </p></p> |
|
|
4楼#
发布于:2005-03-11 09:44
<h3>Enforcing Precision</h3>
Now that the precision needs of a GPS application can bedetermined, it's time to find out what source code is necessary toextract and enforce maximum DOP values. All DOP measurements arepackaged into the $GPGSA sentence every few seconds. Here is a sampleof a $GPGSA sentence: </p><ul><code>$GPGSA,A,3,11,29,07,08,5,17,24,,,,,,2.3,1.2,2.0*30 </code></ul><p>A skillful GPSapplication developer could know if positional readings are preciseenough to use just by looking at one $GPGSA sentence. Again, the bestDOP ratings occur when there are several satellites involved in a fixand the satellites are evenly distributed throughout the sky and atseparate elevations — hitting the GPS device from all angles, so tospeak. </p><p> The last three words of this sentence are 2.3, 1.2, and2.0, representing mean, horizontal and vertical DOP, respectively. Thissentence represents a high-precision environment (suitable enough forboth golfing and driving). Using the final listing from <a href="http://www.codeguru.com/vb/mobile/pocketpc/article.php/c8079/" target="_blank" >part one</a>of this article (Listing 1-8), a method called "ParseGPGSA" is addedwhich extracts DOP values and reports them via three events:HDOPReceived, VDOPReceived, and PDOPReceived. </p><ul> </ul> |
|
|
5楼#
发布于:2005-03-11 09:47
[C#]</p><pre>// ********************************************************************* // ** A high-precision NMEA interpreter // ** Written by Jon Person, author of "GPS.NET" (www.gpsdotnet.com) // ********************************************************************* using System; using System.Globalization; public class NmeaInterpreter { // Represents the EN-US culture, used for numers in NMEA sentences public static CultureInfo NmeaCultureInfo = new CultureInfo("en-US"); // Used to convert knots into miles per hour public static double MPHPerKnot = double.Parse("1.150779", NmeaCultureInfo); #region Delegates public delegate void PositionReceivedEventHandler(string latitude, string longitude); public delegate void DateTimeChangedEventHandler(System.DateTime dateTime); public delegate void BearingReceivedEventHandler(double bearing); public delegate void SpeedReceivedEventHandler(double speed); public delegate void SpeedLimitReachedEventHandler(); public delegate void FixObtainedEventHandler(); public delegate void FixLostEventHandler(); public delegate void SatelliteReceivedEventHandler( int pseudoRandomCode, int azimuth, int elevation, int signalToNoiseRatio); public delegate void HDOPReceivedEventHandler(double value); public delegate void VDOPReceivedEventHandler(double value); public delegate void PDOPReceivedEventHandler(double value); #endregion #region Events public event PositionReceivedEventHandler PositionReceived; public event DateTimeChangedEventHandler DateTimeChanged; public event BearingReceivedEventHandler BearingReceived; public event SpeedReceivedEventHandler SpeedReceived; public event SpeedLimitReachedEventHandler SpeedLimitReached; public event FixObtainedEventHandler FixObtained; public event FixLostEventHandler FixLost; public event SatelliteReceivedEventHandler SatelliteReceived; public event HDOPReceivedEventHandler HDOPReceived; public event VDOPReceivedEventHandler VDOPReceived; public event PDOPReceivedEventHandler PDOPReceived; #endregion // Processes information from the GPS receiver public bool Parse(string sentence) { // Discard the sentence if its checksum does not match our // calculated checksum if (!IsValid(sentence)) return false; // Look at the first word to decide where to go next switch (GetWords(sentence)[0]) { case "$GPRMC": // A "Recommended Minimum" sentence was found! return ParseGPRMC(sentence); case "$GPGSV": // A "Satellites in View" sentence was recieved return ParseGPGSV(sentence); case "$GPGSA": return ParseGPGSA(sentence); default: // Indicate that the sentence was not recognized return false; } } // Divides a sentence into individual words public string[] GetWords(string sentence) { return sentence.Split(','); } // Interprets a $GPRMC message public bool ParseGPRMC(string sentence) { // Divide the sentence into words string[] Words = GetWords(sentence); // Do we have enough values to describe our location? if (Words[3] != "" ; Words[4] != "" ; Words[5] != "" ; Words[6] != "") { // Yes. Extract latitude and longitude // Append hours string Latitude = Words[3].Substring(0, 2) + "0"; // Append minutes Latitude = Latitude + Words[3].Substring(2) + "\""; // Append hours Latitude = Latitude + Words[4]; // Append the hemisphere string Longitude = Words[5].Substring(0, 3) + "0"; // Append minutes Longitude = Longitude + Words[5].Substring(3) + "\""; // Append the hemisphere Longitude = Longitude + Words[6]; // Notify the calling application of the change if(PositionReceived != null) PositionReceived(Latitude, Longitude); } // Do we have enough values to parse satellite-derived time? if (Words[1] != "") { // Yes. Extract hours, minutes, seconds and milliseconds int UtcHours = Convert.ToInt32(Words[1].Substring(0, 2)); int UtcMinutes = Convert.ToInt32(Words[1].Substring(2, 2)); int UtcSeconds = Convert.ToInt32(Words[1].Substring(4, 2)); int UtcMilliseconds = 0; // Extract milliseconds if it is available if (Words[1].Length > 7) { UtcMilliseconds = Convert.ToInt32(Words[1].Substring(7)); } // Now build a DateTime object with all values System.DateTime Today = System.DateTime.Now.ToUniversalTime(); System.DateTime SatelliteTime = new System.DateTime(Today.Year, Today.Month, Today.Day, UtcHours, UtcMinutes, UtcSeconds, UtcMilliseconds); // Notify of the new time, adjusted to the local time zone if(DateTimeChanged != null) DateTimeChanged(SatelliteTime.ToLocalTime()); } // Do we have enough information to extract the current speed? if (Words[7] != "") { // Yes. Parse the speed and convert it to MPH double Speed = double.Parse(Words[7], NmeaCultureInfo) * MPHPerKnot; // Notify of the new speed if(SpeedReceived != null) SpeedReceived(Speed); // Are we over the highway speed limit? if (Speed > 55) if(SpeedLimitReached != null) SpeedLimitReached(); } // Do we have enough information to extract bearing? if (Words[8] != "") { // Indicate that the sentence was recognized double Bearing = double.Parse(Words[8], NmeaCultureInfo); if(BearingReceived != null) BearingReceived(Bearing); } // Does the device currently have a satellite fix? if (Words[2] != "") { switch (Words[2]) { case "A": if(FixObtained != null) FixObtained(); break; case "V": if(FixLost != null) FixLost(); break; } } // Indicate that the sentence was recognized return true; } // Interprets a "Satellites in View" NMEA sentence public bool ParseGPGSV(string sentence) { int PseudoRandomCode = 0; int Azimuth = 0; int Elevation = 0; int SignalToNoiseRatio = 0; // Divide the sentence into words string[] Words = GetWords(sentence); // Each sentence contains four blocks of satellite information. // Read each block and report each satellite's information int Count = 0; for (Count = 1; Count <= 4; Count++) { // Does the sentence have enough words to analyze? if ((Words.Length - 1) >= (Count * 4 + 3)) { // Yes. Proceed with analyzing the block. // Does it contain any information? if (Words[Count * 4] != "" ; Words[Count * 4 + 1] != "" ; Words[Count * 4 + 2] != "" ; Words[Count * 4 + 3] != "") { // Yes. Extract satellite information and report it PseudoRandomCode = System.Convert.ToInt32(Words[Count * 4]); Elevation = Convert.ToInt32(Words[Count * 4 + 1]); Azimuth = Convert.ToInt32(Words[Count * 4 + 2]); SignalToNoiseRatio = Convert.ToInt32(Words[Count * 4 + 2]); // Notify of this satellite's information if(SatelliteReceived != null) SatelliteReceived(PseudoRandomCode, Azimuth, Elevation, SignalToNoiseRatio); } } } // Indicate that the sentence was recognized return true; } // Interprets a "Fixed Satellites and DOP" NMEA sentence public bool ParseGPGSA(string sentence) { // Divide the sentence into words string[] Words = GetWords(sentence); // Update the DOP values if (Words[15] != "") { if(PDOPReceived != null) PDOPReceived(double.Parse(Words[15], NmeaCultureInfo)); } if (Words[16] != "") { if(HDOPReceived != null) HDOPReceived(double.Parse(Words[16], NmeaCultureInfo)); } if (Words[17] != "") { if(VDOPReceived != null) VDOPReceived(double.Parse(Words[17], NmeaCultureInfo)); } return true; } // Returns True if a sentence's checksum matches the // calculated checksum public bool IsValid(string sentence) { // Compare the characters after the asterisk to the calculation return sentence.Substring(sentence.IndexOf("*") + 1) == GetChecksum(sentence); } // Calculates the checksum for a sentence public string GetChecksum(string sentence) { // Loop through all chars to get a checksum int Checksum = 0; foreach (char Character in sentence) { if (Character == '$') { // Ignore the dollar sign } else if (Character == '*') { // Stop processing before the asterisk break; } else { // Is this the first value for the checksum? if (Checksum == 0) { // Yes. Set the checksum to the value Checksum = Convert.ToByte(Character); } else { // No. XOR the checksum with this character's value Checksum = Checksum ^ Convert.ToByte(Character); } } } // Return the checksum formatted as a two-character hexadecimal return Checksum.ToString("X2"); } } </pre><p>[VB.NET] </p><pre>' ********************************************************************* ' ** A high-precision NMEA interpreter ' ** Written by Jon Person, author of "GPS.NET" (www.gpsdotnet.com) ' ********************************************************************* Imports System Imports System.Globalization Public Class NmeaInterpreter ' Represents the EN-US culture, used for numers in NMEA sentences Public Shared NmeaCultureInfo As New CultureInfo("en-US") ' Used to convert knots into miles per hour Public Shared MPHPerKnot As Double = Double.Parse("1.150779", _ NmeaCultureInfo) ' Raised when the current location has changed Public Event PositionReceived(ByVal latitude As String, _ ByVal longitude As String) Public Event DateTimeChanged(ByVal dateTime As DateTime) Public Event BearingReceived(ByVal bearing As Double) Public Event SpeedReceived(ByVal speed As Double) Public Event SpeedLimitReached() Public Event FixObtained() Public Event FixLost() Public Event SatelliteReceived(ByVal pseudoRandomCode As Integer, _ ByVal azimuth As Integer, _ ByVal elevation As Integer, _ ByVal signalToNoiseRatio As Integer) Public Event HDOPReceived(ByVal value As Double) Public Event VDOPReceived(ByVal value As Double) Public Event PDOPReceived(ByVal value As Double) ' Processes information from the GPS receiver Public Function Parse(ByVal sentence As String) As Boolean ' Discard the sentence if its checksum does not match our ' calculated checksum If Not IsValid(sentence) Then Return False ' Look at the first word to decide where to go next Select Case GetWords(sentence)(0) Case "$GPRMC" ' A "Recommended Minimum" sentence was found! Return ParseGPRMC(sentence) Case "$GPGSV" ' A "Satellites in View" sentence was recieved Return ParseGPGSV(sentence) Case "$GPGSA" Return ParseGPGSA(sentence) Case Else ' Indicate that the sentence was not recognized Return False End Select End Function ' Divides a sentence into individual words Public Function GetWords(ByVal sentence As String) As String() Return sentence.Split(","c) End Function ' Interprets a $GPRMC message Public Function ParseGPRMC(ByVal sentence As String) As Boolean ' Divide the sentence into words Dim Words() As String = GetWords(sentence) ' Do we have enough values to describe our location? If Words(3) <> "" And Words(4) <> "" _ And Words(5) <> "" And Words(6) <> "" Then ' Yes. Extract latitude and longitude ' Append hours Dim Latitude As String = Words(3).Substring(0, 2) ; "0" ' Append minutes Latitude = Latitude ; Words(3).Substring(2) ; """" ' Append the hemisphere Latitude = Latitude ; Words(4) ' Append hours Dim Longitude As String = Words(5).Substring(0, 3) ; "0" ' Append minutes Longitude = Longitude ; Words(5).Substring(3) ; """" ' Append the hemisphere Longitude = Longitude ; Words(6) ' Notify the calling application of the change RaiseEvent PositionReceived(Latitude, Longitude) End If ' Do we have enough values to parse satellite-derived time? If Words(1) <> "" Then ' Yes. Extract hours, minutes, seconds and milliseconds Dim UtcHours As Integer = CType(Words(1).Substring(0, 2), Integer) Dim UtcMinutes As Integer = CType(Words(1).Substring(2, 2), Integer) Dim UtcSeconds As Integer = CType(Words(1).Substring(4, 2), Integer) Dim UtcMilliseconds As Integer ' Extract milliseconds if it is available If Words(1).Length > 7 Then UtcMilliseconds = _ CType(Words(1).Substring(7), Integer) ' Now build a DateTime object with all values Dim Today As DateTime = System.DateTime.Now.ToUniversalTime Dim SatelliteTime As New System.DateTime(Today.Year, Today.Month, Today.Day, UtcHours, UtcMinutes, UtcSeconds, UtcMilliseconds) ' Notify of the new time, adjusted to the local time zone RaiseEvent DateTimeChanged(SatelliteTime.ToLocalTime) End If ' Do we have enough information to extract the current speed? If Words(7) <> "" Then ' Yes. Parse the speed and convert it to MPH Dim Speed As Double = Double.Parse(Words(7), NmeaCultureInfo) * MPHPerKnot ' Notify of the new speed RaiseEvent SpeedReceived(Speed) ' Are we over the highway speed limit? If Speed > 55 Then RaiseEvent SpeedLimitReached() End If ' Do we have enough information to extract bearing? If Words(8) <> "" Then ' Indicate that the sentence was recognized Dim Bearing As Double = Double.Parse(Words(8), NmeaCultureInfo) RaiseEvent BearingReceived(Bearing) End If ' Does the device currently have a satellite fix? If Words(2) <> "" Then Select Case Words(2) Case "A" RaiseEvent FixObtained() Case "V" RaiseEvent FixLost() End Select End If ' Indicate that the sentence was recognized Return True End Function ' Interprets a "Satellites in View" NMEA sentence Public Function ParseGPGSV(ByVal sentence As String) As Boolean Dim PseudoRandomCode As Integer Dim Azimuth As Integer Dim Elevation As Integer Dim SignalToNoiseRatio As Integer ' Divide the sentence into words Dim Words() As String = GetWords(sentence) ' Each sentence contains four blocks of satellite information. ' Read each block and report each satellite's information Dim Count As Integer For Count = 1 To 4 ' Does the sentence have enough words to analyze? If (Words.Length - 1) >= (Count * 4 + 3) Then ' Yes. Proceed with analyzing the block. ' Does it contain any information? If Words(Count * 4) <> "" And Words(Count * 4 + 1) <> "" _ And Words(Count * 4 + 2) <> "" And Words(Count * 4 + 3) <> "" Then ' Yes. Extract satellite information and report it PseudoRandomCode = CType(Words(Count * 4), Integer) Elevation = CType(Words(Count * 4 + 1), Integer) Azimuth = CType(Words(Count * 4 + 2), Integer) SignalToNoiseRatio = CType(Words(Count * 4 + 2), Integer) ' Notify of this satellite's information RaiseEvent SatelliteReceived(PseudoRandomCode, Azimuth, _ Elevation, SignalToNoiseRatio) End If End If Next ' Indicate that the sentence was recognized Return True End Function ' Interprets a "Fixed Satellites and DOP" NMEA sentence Public Function ParseGPGSA(ByVal sentence As String) As Boolean ' Divide the sentence into words Dim Words() As String = GetWords(sentence) ' Update the DOP values If Words(15) <> "" Then RaiseEvent PDOPReceived(Double.Parse(Words(15), NmeaCultureInfo)) End If If Words(16) <> "" Then RaiseEvent HDOPReceived(Double.Parse(Words(16), NmeaCultureInfo)) End If If Words(17) <> "" Then RaiseEvent VDOPReceived(Double.Parse(Words(17), NmeaCultureInfo)) End If Return True End Function ' Returns True if a sentence's checksum matches the calculated checksum Public Function IsValid(ByVal sentence As String) As Boolean ' Compare the characters after the asterisk to the calculation Return sentence.Substring(sentence.IndexOf("*") + 1) = _ GetChecksum(sentence) End Function ' Calculates the checksum for a sentence Public Function GetChecksum(ByVal sentence As String) As String ' Loop through all chars to get a checksum Dim Character As Char Dim Checksum As Integer For Each Character In sentence Select Case Character Case "$"c ' Ignore the dollar sign Case "*"c ' Stop processing before the asterisk Exit For Case Else ' Is this the first value for the checksum? If Checksum = 0 Then ' Yes. Set the checksum to the value Checksum = Convert.ToByte(Character) Else ' No. XOR the checksum with this character's value Checksum = Checksum Xor Convert.ToByte(Character) End If End Select Next ' Return the checksum formatted as a two-character hexadecimal Return Checksum.ToString("X2") End Function End Class</pre> |
|
|
6楼#
发布于:2005-03-11 09:49
<h3>High Precision in Action</h3>
Enforcing maximum DOP values is the easiest part of the wholeprogramming process because enforcing precision is a matter of ignoringpositional measurements above your maximum allowable DOP amount. Thiscan be done in one "if" statement. To best demonstrate this, I'vewritten a small application (the "Demo" linked at the start of thisarticle) which uses the NMEA interpreter to enforce a maximum DOP of 6. <p>[C#] </p><pre>public class HighPrecisionTest { private NmeaInterpreter MyInterpreter = new NmeaInterpreter(); private int MaximumDOPAllowed = 6; private double CurrentHDOP; public HighPrecisionTest() { // Bind events for dilution of position MyInterpreter.HDOPReceived += new System.EventHandler(OnHDOPReceived); MyInterpreter.PositionReceived += new System.EventHandler(OnPositionReceived); } public void Test() { // Parse satellite information (HDOP is 50.0) MyInterpreter.Parse( "$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05"); // Parse the current position MyInterpreter.Parse( "$GPRMC,225233.990,V,3939.4000,N,10506.4000,W,0.00,51.40,280804,,*35"); // Parse satellite information (HDOP is 1.2) MyInterpreter.Parse( "$GPGSA,A,3,11,29,07,08,19,28,26,,,,,,2.3,1.2,2.0*30"); // Parse the current position again MyInterpreter.Parse( "$GPRMC,012558.584,A,3939.7000,N,10506.7000,W,0.00,198.07,290804,,*11"); } private void OnHDOPReceived(double value) { // Remember the current HDOP value CurrentHDOP = value; } private void OnPositionReceived(string latitude, string longitude) { // Is the HDOP at least six? if (CurrentHDOP <= MaximumDOPAllowed) { // Yes. Display the current position Debug.WriteLine("You are here: " + latitude + ", " + longitude); } else { // No. Discard this positional measurement Debug.WriteLine("The received location is not precise enough to use."); } } } </pre><p>[VB.NET] </p><pre>Public Class HighPrecisionTest Private WithEvents MyInterpreter As New NmeaInterpreter Private MaximumDOPAllowed As Integer = 6 Private CurrentHDOP As Double Public Sub Test() ' Parse satellite information (HDOP is 50.0) MyInterpreter.Parse("$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05") ' Parse the current position MyInterpreter.Parse("$GPRMC,225233.990,V,3939.4000,N,10506.4000,W,0.00,51.40,280804,,*35") ' Parse satellite information (HDOP is 1.2) MyInterpreter.Parse("$GPGSA,A,3,11,29,07,08,19,28,26,,,,,,2.3,1.2,2.0*30") ' Parse the current position again MyInterpreter.Parse("$GPRMC,012558.584,A,3939.7000,N,10506.7000,W,0.00,198.07,290804,,*11") End Sub Private Sub OnHDOPReceived(ByVal value As Double) Handles MyInterpreter.HDOPReceived ' Remember the current HDOP value CurrentHDOP = value End Sub Private Sub OnPositionReceived(ByVal latitude As String, _ ByVal longitude As String) Handles MyInterpreter.PositionReceived ' Is the HDOP at least six? If CurrentHDOP <= MaximumDOPAllowed Then ' Yes. Display the current position Debug.WriteLine("You are here: " ; latitude ; ", " ; longitude) Else ' No. Discard this positional measurement Debug.WriteLine("The received location is not precise enough to use.") End If End Sub End Class </pre><p> And that's it! Armed with a deep understanding of GPS precisionand how to keep it tightly controlled, you can now developlocation-based services suitable for the real world. </p> </p> |
|
|
7楼#
发布于:2005-03-11 09:52
<h3>Conclusion</h3> There are several ways to distort a GPS satellite signal; some arecorrected by the Department of Defense and others can be corrected inyour GPS receiver using real-time ground station correction signals.The only precision problem which is left to you to control is GeometricDilution of Precision. Controlling GDOP is the key to writingcommercial-grade GPS applications. A small mathematical formula can beapplied to determine the maximum allowable DOP for a particularapplication. The maximum allowable error should be the greatestpossible value which minimizes accuracy problems while maximizingoperational conditions.
Another factor which helps developers is time itself.Advances in GPS receiver technology are pushing precision to newlevels. While precision can be questionable with any consumer GPSdevice, there will soon be a time when precision to a centimeter ispossible. I believe that this level of precision will cause arevolution in industry and pave the way for some truly amazing things:automated construction machines, tracking for every shipping containerin the world, traffic control systems that actively prevent trafficjams... and self-guiding golf balls. </p> |
|
|
8楼#
发布于:2005-03-11 10:16
<img src="images/post/smile/dvbbs/em05.gif" /><img src="images/post/smile/dvbbs/em06.gif" /><img src="images/post/smile/dvbbs/em08.gif" /> |
|
|
9楼#
发布于:2005-03-24 01:12
<img src="images/post/smile/dvbbs/em02.gif" />
|
|