技术开发 频道

WM平台上如何开发出自己的GPS导航

  正如你所看到的,一大堆的信息都装在NMEA一句话中。现在$ GPRMC语句已经被充分解析,解析器可以扩展以支持第二句:$ GPGSV。这句话描述了卫星配置的开销,实时。

  实时卫星追踪

  在确定如何精确读数,以及如何稳定的一个GPS的修补程序时,知道卫星的位置非常重要。全球定位系统的精度将会在系列的第2部分详细介绍,本节将侧重于判读卫星的位置和信号强度。有24颗卫星在轨道上运行。卫星在轨道的间距,以便在任何时间至少6颗卫星将被世界各地的用户用到。卫星不断运动,这是好事,因为它阻止很少或根本不会出现卫星可见的“世界上存在的盲点”。就像在寻找天上的星星,卫星的位置被描述为一个方位和海拔的组合。

  如上所述,方位角测量了围绕地平线的方向。海拔测量值在一定程度从0 °至90 °,其中0 °表示地平线,90 °代表“顶峰”,直接开销。因此,如果设备说卫星的方位角为45 °,其海拔为45 °,卫星位于半山腰,从东北方向的地平线。除了位置,设备报告每个卫星的“伪随机码”(或PRC),这个数字用于唯一地标识从一个卫星到另一个卫星。以下是 $ GPGSV语句的例子:

  代码片段:

1 $GPGSV,3,1,10,24,82,023,40,05,62,285,32,01,62,123,00,17,59,229,28*70

  每个句子包含多达4个卫星信息块,由4个字组成的。例如,第一块是“24,82,023,40”,第二块是“05,62,285,32”等。每个块的第一个字给出了卫星的PRC。第二个单词给出每颗卫星的高度,方位和所遵循的信号强度。如果这个卫星信息将被显示图形,它的样子会是如图1-1。

  也许,这句话中最重要的数字是“信号噪声比”(或简称信噪比)。此数字表示卫星的无线电信号被接收的强烈程度。请记住,卫星传输相同强度的信号,但像树木和墙壁这样的东西可能掩盖一个信号。典型的信噪比值介于0和50,其中50是指一个很好的信号。 (信噪比可高达99,但我从来没有见过,即使在开阔的天空读数也是50。)在图1-1中,绿色的卫星表明一个强烈的信号,而黄色的卫星,标志着一个温和的信号(第2部分中,我将提供一种方法进行分类信号强度)。 #1卫星的信号是完全掩盖。列表1-7显示的是解析器在它扩大为用于读取卫星信息。

  代码片段:

  1 '*******************************************************
  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
0
相关文章