正如你所看到的,一大堆的信息都装在NMEA一句话中。现在$ GPRMC语句已经被充分解析,解析器可以扩展以支持第二句:$ GPGSV。这句话描述了卫星配置的开销,实时。
实时卫星追踪
在确定如何精确读数,以及如何稳定的一个GPS的修补程序时,知道卫星的位置非常重要。全球定位系统的精度将会在系列的第2部分详细介绍,本节将侧重于判读卫星的位置和信号强度。有24颗卫星在轨道上运行。卫星在轨道的间距,以便在任何时间至少6颗卫星将被世界各地的用户用到。卫星不断运动,这是好事,因为它阻止很少或根本不会出现卫星可见的“世界上存在的盲点”。就像在寻找天上的星星,卫星的位置被描述为一个方位和海拔的组合。
如上所述,方位角测量了围绕地平线的方向。海拔测量值在一定程度从0 °至90 °,其中0 °表示地平线,90 °代表“顶峰”,直接开销。因此,如果设备说卫星的方位角为45 °,其海拔为45 °,卫星位于半山腰,从东北方向的地平线。除了位置,设备报告每个卫星的“伪随机码”(或PRC),这个数字用于唯一地标识从一个卫星到另一个卫星。以下是 $ GPGSV语句的例子:
代码片段:
每个句子包含多达4个卫星信息块,由4个字组成的。例如,第一块是“24,82,023,40”,第二块是“05,62,285,32”等。每个块的第一个字给出了卫星的PRC。第二个单词给出每颗卫星的高度,方位和所遵循的信号强度。如果这个卫星信息将被显示图形,它的样子会是如图1-1。

也许,这句话中最重要的数字是“信号噪声比”(或简称信噪比)。此数字表示卫星的无线电信号被接收的强烈程度。请记住,卫星传输相同强度的信号,但像树木和墙壁这样的东西可能掩盖一个信号。典型的信噪比值介于0和50,其中50是指一个很好的信号。 (信噪比可高达99,但我从来没有见过,即使在开阔的天空读数也是50。)在图1-1中,绿色的卫星表明一个强烈的信号,而黄色的卫星,标志着一个温和的信号(第2部分中,我将提供一种方法进行分类信号强度)。 #1卫星的信号是完全掩盖。列表1-7显示的是解析器在它扩大为用于读取卫星信息。
代码片段:
2
3 '** Listing 1-7. Extracting satellite information
4
5 '*******************************************************
6
7 Public Class NmeaInterpreter
8
9 ' Raised when the current location has changed
10
11 Public Event PositionReceived(ByVal latitude As String, _
12 ByVal longitude As String)
13 Public Event DateTimeChanged(ByVal dateTime As DateTime)
14 Public Event BearingReceived(ByVal bearing As Double)
15 Public Event SpeedReceived(ByVal speed As Double)
16 Public Event SpeedLimitReached()
17 Public Event FixObtained()
18 Public Event FixLost()
19 Public Event SatelliteReceived(ByVal pseudoRandomCode As Integer, _
20 ByVal azimuth As Integer, _
21 ByVal elevation As Integer, _
22 ByVal signalToNoiseRatio As Integer)
23 ' Processes information from the GPS receiver
24 Public Function Parse(ByVal sentence As String) As Boolean
25 ' Discard the sentence if its checksum does not match our calculated
26 ' checksum
27 If Not IsValid(sentence) Then Return False
28 ' Look at the first word to decide where to go next
29 Select Case GetWords(sentence)(0)
30 Case "$GPRMC" ' A "Recommended Minimum" sentence was found!
31 Return ParseGPRMC(sentence)
32 Case "$GPGSV" ' A "Satellites in View" message was found
33 Return ParseGPGSV(sentence)
34 Case Else
35 ' Indicate that the sentence was not recognized
36 Return False
37 End Select
38 End Function
39 ' Divides a sentence into individual words
40 Public Function GetWords(ByVal sentence As String) As String()
41 Return sentence.Split(","c)
42 End Function
43 ' Interprets a $GPRMC message
44 Public Function ParseGPRMC(ByVal sentence As String) As Boolean
45 ' Divide the sentence into words
46 Dim Words() As String = GetWords(sentence)
47 ' Do we have enough values to describe our location?
48 If Words(3) <> "" And Words(4) <> "" And Words(5) <> "" And _
49 Words(6) <> "" Then
50 ' Yes. Extract latitude and longitude
51 Dim Latitude As String = Words(3).Substring(0, 2) & "°" ' Append hours
52 Latitude = Latitude & Words(3).Substring(2) & """" ' Append minutes
53 Latitude = Latitude & Words(4) ' Append the hemisphere
54 Dim Longitude As String = Words(5).Substring(0, 3) & "°" ' Append hours
55 Longitude = Longitude & Words(5).Substring(3) & """" ' Append minutes
56 Longitude = Longitude & Words(6) ' Append the hemisphere
57 ' Notify the calling application of the change
58 RaiseEvent PositionReceived(Latitude, Longitude)
59 End If
60 ' Do we have enough values to parse satellite-derived time?
61 If Words(1) <> "" Then
62 ' Yes. Extract hours, minutes, seconds and milliseconds
63 Dim UtcHours As Integer = CType(Words(1).Substring(0, 2), Integer)
64 Dim UtcMinutes As Integer = CType(Words(1).Substring(2, 2), Integer)
65 Dim UtcSeconds As Integer = CType(Words(1).Substring(4, 2), Integer)
66 Dim UtcMilliseconds As Integer
67 ' Extract milliseconds if it is available
68 If Words(1).Length > 7 Then UtcMilliseconds = _
69 CType(Single.Parse(Words(1).Substring(6), _
70 CultureInfo.InvariantCulture) * 1000, Integer)
71 ' Now build a DateTime object with all values
72 Dim Today As DateTime = System.DateTime.Now.ToUniversalTime
73 Dim SatelliteTime As New System.DateTime(Today.Year, Today.Month, _
74 Today.Day, UtcHours, UtcMinutes, UtcSeconds, UtcMilliseconds)
75 ' Notify of the new time, adjusted to the local time zone
76 RaiseEvent DateTimeChanged(SatelliteTime.ToLocalTime)
77 End If
78 ' Do we have enough information to extract the current speed?
79 If Words(7) <> "" Then
80 ' Yes. Convert it into MPH
81 Dim Speed As Double = CType(Words(7), Double) * 1.150779
82 ' If we're over 55MPH then trigger a speed alarm!
83 If Speed > 55 Then RaiseEvent SpeedLimitReached()
84 ' Notify of the new speed
85 RaiseEvent SpeedReceived(Speed)
86 End If
87 ' Do we have enough information to extract bearing?
88 If Words(8) <> "" Then
89 ' Indicate that the sentence was recognized
90 Dim Bearing As Double = CType(Words(8), Double)
91 RaiseEvent BearingReceived(Bearing)
92 End If
93 ' Does the device currently have a satellite fix?
94 If Words(2) <> "" Then
95 Select Case Words(2)
96 Case "A"
97 RaiseEvent FixObtained()
98 Case "V"
99 RaiseEvent FixLost()
100 End Select
101 End If
102 ' Indicate that the sentence was recognized
103 Return True
104 End Function
105 ' Interprets a "Satellites in View" NMEA sentence
106 Public Function ParseGPGSV(ByVal sentence As String) As Boolean
107 Dim PseudoRandomCode As Integer
108 Dim Azimuth As Integer
109 Dim Elevation As Integer
110 Dim SignalToNoiseRatio As Integer
111 ' Divide the sentence into words
112 Dim Words() As String = GetWords(sentence)
113 ' Each sentence contains four blocks of satellite information.
114 ' Read each block and report each satellite's information
115 Dim Count As Integer
116 For Count = 1 To 4
117 ' Does the sentence have enough words to analyze?
118 If (Words.Length - 1) >= (Count * 4 + 3) Then
119 ' Yes. Proceed with analyzing the block. Does it contain any
120 ' information?
121 If Words(Count * 4) <> "" And Words(Count * 4 + 1) <> "" _
122 And Words(Count * 4 + 2) <> "" And Words(Count * 4 + 3) <> "" Then
123 ' Yes. Extract satellite information and report it
124 PseudoRandomCode = CType(Words(Count * 4), Integer)
125 Elevation = CType(Words(Count * 4 + 1), Integer)
126 Azimuth = CType(Words(Count * 4 + 2), Integer)
127 SignalToNoiseRatio = CType(Words(Count * 4 + 2), Integer)
128 ' Notify of this satellite's information
129 RaiseEvent SatelliteReceived(PseudoRandomCode, Azimuth, Elevation, _
130 SignalToNoiseRatio)
131 End If
132 End If
133 Next
134 ' Indicate that the sentence was recognized
135 Return True
136 End Function
137 ' Returns True if a sentence's checksum matches the calculated checksum
138 Public Function IsValid(ByVal sentence As String) As Boolean
139 ' Compare the characters after the asterisk to the calculation
140 Return sentence.Substring(sentence.IndexOf("*") + 1) = GetChecksum(sentence)
141 End Function
142 ' Calculates the checksum for a sentence
143 Public Function GetChecksum(ByVal sentence As String) As String
144 ' Loop through all chars to get a checksum
145 Dim Character As Char
146 Dim Checksum As Integer
147 For Each Character In sentence
148 Select Case Character
149 Case "$"c
150 ' Ignore the dollar sign
151 Case "*"c
152 ' Stop processing before the asterisk
153 Exit For
154 Case Else
155 ' Is this the first value for the checksum?
156 If Checksum = 0 Then
157 ' Yes. Set the checksum to the value
158 Checksum = Convert.ToByte(Character)
159 Else
160 ' No. XOR the checksum with this character's value
161 Checksum = Checksum Xor Convert.ToByte(Character)
162 End If
163 End Select
164 Next
165 ' Return the checksum formatted as a two-character hexadecimal
166 Return Checksum.ToString("X2")
167 End Function
168 End Class
169