Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: third_party/twisted_8_1/twisted/protocols/gps/rockwell.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4
5 """Rockwell Semiconductor Zodiac Serial Protocol
6 Coded from official protocol specs (Order No. GPS-25, 09/24/1996, Revision 11)
7
8 Maintainer: U{Bob Ippolito<mailto:bob@redivi.com>}
9
10 The following Rockwell Zodiac messages are currently understood::
11 EARTHA\\r\\n (a hack to "turn on" a DeLorme Earthmate)
12 1000 (Geodesic Position Status Output)
13 1002 (Channel Summary)
14 1003 (Visible Satellites)
15 1011 (Receiver ID)
16
17 The following Rockwell Zodiac messages require implementation::
18 None really, the others aren't quite so useful and require bidirectional com munication w/ the device
19
20 Other desired features::
21 - Compatability with the DeLorme Tripmate and other devices with this chipse t (?)
22 """
23
24 import struct, operator, math
25 from twisted.internet import protocol
26 from twisted.python import log
27
28 DEBUG = 1
29
30 class ZodiacParseError(ValueError):
31 pass
32
33 class Zodiac(protocol.Protocol):
34 dispatch = {
35 # Output Messages (* means they get sent by the receiver by default periodic ally)
36 1000: 'fix', # *Geodesic Position Status Output
37 1001: 'ecef', # ECEF Position Status Output
38 1002: 'channels', # *Channel Summary
39 1003: 'satellites', # *Visible Satellites
40 1005: 'dgps', # Differential GPS Status
41 1007: 'channelmeas', # Channel Measurement
42 1011: 'id', # *Receiver ID
43 1012: 'usersettings', # User-Settings Output
44 1100: 'testresults', # Built-In Test Results
45 1102: 'meastimemark', # Measurement Time Mark
46 1108: 'utctimemark', # UTC Time Mark Pulse Output
47 1130: 'serial', # Serial Port Communication Parameters In Use
48 1135: 'eepromupdate', # EEPROM Update
49 1136: 'eepromstatus', # EEPROM Status
50 }
51 # these aren't used for anything yet, just sitting here for reference
52 messages = {
53 # Input Messages
54 'fix': 1200, # Geodesic Position and Velocity Initialization
55 'udatum': 1210, # User-Defined Datum Definition
56 'mdatum': 1211, # Map Datum Select
57 'smask': 1212, # Satellite Elevation Mask Control
58 'sselect': 1213, # Satellite Candidate Select
59 'dgpsc': 1214, # Differential GPS Control
60 'startc': 1216, # Cold Start Control
61 'svalid': 1217, # Solution Validity Control
62 'antenna': 1218, # Antenna Type Select
63 'altinput': 1219, # User-Entered Altitude Input
64 'appctl': 1220, # Application Platform Control
65 'navcfg': 1221, # Nav Configuration
66 'test': 1300, # Perform Built-In Test Command
67 'restart': 1303, # Restart Command
68 'serial': 1330, # Serial Port Communications Parameters
69 'msgctl': 1331, # Message Protocol Control
70 'dgpsd': 1351, # Raw DGPS RTCM SC-104 Data
71 }
72 MAX_LENGTH = 296
73 allow_earthmate_hack = 1
74 recvd = ""
75
76 def dataReceived(self, recd):
77 self.recvd = self.recvd + recd
78 while len(self.recvd) >= 10:
79
80 # hack for DeLorme EarthMate
81 if self.recvd[:8] == 'EARTHA\r\n':
82 if self.allow_earthmate_hack:
83 self.allow_earthmate_hack = 0
84 self.transport.write('EARTHA\r\n')
85 self.recvd = self.recvd[8:]
86 continue
87
88 if self.recvd[0:2] != '\xFF\x81':
89 if DEBUG:
90 raise ZodiacParseError('Invalid Sync %r' % self.recvd)
91 else:
92 raise ZodiacParseError
93 sync, msg_id, length, acknak, checksum = struct.unpack('<HHHHh', self.recv d[:10])
94
95 # verify checksum
96 cksum = -(reduce(operator.add, (sync, msg_id, length, acknak)) & 0xFFFF)
97 cksum, = struct.unpack('<h', struct.pack('<h', cksum))
98 if cksum != checksum:
99 if DEBUG:
100 raise ZodiacParseError('Invalid Header Checksum %r != %r %r' % (checks um, cksum, self.recvd[:8]))
101 else:
102 raise ZodiacParseError
103
104 # length was in words, now it's bytes
105 length = length * 2
106
107 # do we need more data ?
108 neededBytes = 10
109 if length:
110 neededBytes += length + 2
111 if len(self.recvd) < neededBytes:
112 break
113
114 if neededBytes > self.MAX_LENGTH:
115 raise ZodiacParseError("Invalid Header??")
116
117 # empty messages pass empty strings
118 message = ''
119
120 # does this message have data ?
121 if length:
122 message, checksum = self.recvd[10:10+length], struct.unpack('<h', self.r ecvd[10+length:neededBytes])[0]
123 cksum = 0x10000 - (reduce(operator.add, struct.unpack('<%dH' % (length/2 ), message)) & 0xFFFF)
124 cksum, = struct.unpack('<h', struct.pack('<h', cksum))
125 if cksum != checksum:
126 if DEBUG:
127 log.dmsg('msg_id = %r length = %r' % (msg_id, length), debug=True)
128 raise ZodiacParseError('Invalid Data Checksum %r != %r %r' % (checks um, cksum, message))
129 else:
130 raise ZodiacParseError
131
132 # discard used buffer, dispatch message
133 self.recvd = self.recvd[neededBytes:]
134 self.receivedMessage(msg_id, message, acknak)
135
136 def receivedMessage(self, msg_id, message, acknak):
137 dispatch = self.dispatch.get(msg_id, None)
138 if not dispatch:
139 raise ZodiacParseError('Unknown msg_id = %r' % msg_id)
140 handler = getattr(self, 'handle_%s' % dispatch, None)
141 decoder = getattr(self, 'decode_%s' % dispatch, None)
142 if not (handler and decoder):
143 # missing handler or decoder
144 #if DEBUG:
145 # log.msg('MISSING HANDLER/DECODER PAIR FOR: %r' % (dispatch,), debug=Tru e)
146 return
147 decoded = decoder(message)
148 return handler(*decoded)
149
150 def decode_fix(self, message):
151 assert len(message) == 98, "Geodesic Position Status Output should be 55 wor ds total (98 byte message)"
152 (ticks, msgseq, satseq, navstatus, navtype, nmeasure, polar, gpswk, gpses, g psns, utcdy, utcmo, utcyr, utchr, utcmn, utcsc, utcns, latitude, longitude, heig ht, geoidalsep, speed, course, magvar, climb, mapdatum, exhposerr, exvposerr, ex timeerr, exphvelerr, clkbias, clkbiasdev, clkdrift, clkdriftdev) = struct.unpack ('<LhhHHHHHLLHHHHHHLlllhLHhhHLLLHllll', message)
153
154 # there's a lot of shit in here..
155 # I'll just snag the important stuff and spit it out like my NMEA decoder
156 utc = (utchr * 3600.0) + (utcmn * 60.0) + utcsc + (float(utcns) * 0.00000000 1)
157
158 log.msg('utchr, utcmn, utcsc, utcns = ' + repr((utchr, utcmn, utcsc, utcns)) , debug=True)
159
160 latitude = float(latitude) * 0.00000180 / math.pi
161 longitude = float(longitude) * 0.00000180 / math.pi
162 posfix = not (navstatus & 0x001c)
163 satellites = nmeasure
164 hdop = float(exhposerr) * 0.01
165 altitude = float(height) * 0.01, 'M'
166 geoid = float(geoidalsep) * 0.01, 'M'
167 dgps = None
168 return (
169 # seconds since 00:00 UTC
170 utc,
171 # latitude (degrees)
172 latitude,
173 # longitude (degrees)
174 longitude,
175 # position fix status (invalid = False, valid = True)
176 posfix,
177 # number of satellites [measurements] used for fix 0 <= satellites <= 12
178 satellites,
179 # horizontal dilution of precision
180 hdop,
181 # (altitude according to WGS-84 ellipsoid, units (always 'M' for meters))
182 altitude,
183 # (geoid separation according to WGS-84 ellipsoid, units (always 'M' for m eters))
184 geoid,
185 # None, for compatability w/ NMEA code
186 dgps,
187 )
188
189 def decode_id(self, message):
190 assert len(message) == 106, "Receiver ID Message should be 59 words total (1 06 byte message)"
191 ticks, msgseq, channels, software_version, software_date, options_list, rese rved = struct.unpack('<Lh20s20s20s20s20s', message)
192 channels, software_version, software_date, options_list = map(lambda s: s.sp lit('\0')[0], (channels, software_version, software_date, options_list))
193 software_version = float(software_version)
194 channels = int(channels) # 0-12 .. but ALWAYS 12, so we ignore.
195 options_list = int(options_list[:4], 16) # only two bitflags, others are res erved
196 minimize_rom = (options_list & 0x01) > 0
197 minimize_ram = (options_list & 0x02) > 0
198 # (version info), (options info)
199 return ((software_version, software_date), (minimize_rom, minimize_ram))
200
201 def decode_channels(self, message):
202 assert len(message) == 90, "Channel Summary Message should be 51 words total (90 byte message)"
203 ticks, msgseq, satseq, gpswk, gpsws, gpsns = struct.unpack('<LhhHLL', messag e[:18])
204 channels = []
205 message = message[18:]
206 for i in range(12):
207 flags, prn, cno = struct.unpack('<HHH', message[6 * i:6 * (i + 1)])
208 # measurement used, ephemeris available, measurement valid, dgps correctio ns available
209 flags = (flags & 0x01, flags & 0x02, flags & 0x04, flags & 0x08)
210 channels.append((flags, prn, cno))
211 # ((flags, satellite PRN, C/No in dbHz)) for 12 channels
212 # satellite message sequence number
213 # gps week number, gps seconds in week (??), gps nanoseconds from Epoch
214 return (tuple(channels),) #, satseq, (gpswk, gpsws, gpsns))
215
216 def decode_satellites(self, message):
217 assert len(message) == 90, "Visible Satellites Message should be 51 words to tal (90 byte message)"
218 ticks, msgseq, gdop, pdop, hdop, vdop, tdop, numsatellites = struct.unpack(' <LhhhhhhH', message[:18])
219 gdop, pdop, hdop, vdop, tdop = map(lambda n: float(n) * 0.01, (gdop, pdop, h dop, vdop, tdop))
220 satellites = []
221 message = message[18:]
222 for i in range(numsatellites):
223 prn, azi, elev = struct.unpack('<Hhh', message[6 * i:6 * (i + 1)])
224 azi, elev = map(lambda n: (float(n) * 0.0180 / math.pi), (azi, elev))
225 satellites.push((prn, azi, elev))
226 # ((PRN [0, 32], azimuth +=[0.0, 180.0] deg, elevation +-[0.0, 90.0] deg)) s atellite info (0-12)
227 # (geometric, position, horizontal, vertical, time) dilution of precision
228 return (tuple(satellites), (gdop, pdop, hdop, vdop, tdop))
229
230 def decode_dgps(self, message):
231 assert len(message) == 38, "Differential GPS Status Message should be 25 wor ds total (38 byte message)"
232 raise NotImplementedError
233
234 def decode_ecef(self, message):
235 assert len(message) == 96, "ECEF Position Status Output Message should be 54 words total (96 byte message)"
236 raise NotImplementedError
237
238 def decode_channelmeas(self, message):
239 assert len(message) == 296, "Channel Measurement Message should be 154 words total (296 byte message)"
240 raise NotImplementedError
241
242 def decode_usersettings(self, message):
243 assert len(message) == 32, "User-Settings Output Message should be 22 words total (32 byte message)"
244 raise NotImplementedError
245
246 def decode_testresults(self, message):
247 assert len(message) == 28, "Built-In Test Results Message should be 20 words total (28 byte message)"
248 raise NotImplementedError
249
250 def decode_meastimemark(self, message):
251 assert len(message) == 494, "Measurement Time Mark Message should be 253 wor ds total (494 byte message)"
252 raise NotImplementedError
253
254 def decode_utctimemark(self, message):
255 assert len(message) == 28, "UTC Time Mark Pulse Output Message should be 20 words total (28 byte message)"
256 raise NotImplementedError
257
258 def decode_serial(self, message):
259 assert len(message) == 30, "Serial Port Communication Paramaters In Use Mess age should be 21 words total (30 byte message)"
260 raise NotImplementedError
261
262 def decode_eepromupdate(self, message):
263 assert len(message) == 8, "EEPROM Update Message should be 10 words total (8 byte message)"
264 raise NotImplementedError
265
266 def decode_eepromstatus(self, message):
267 assert len(message) == 24, "EEPROM Status Message should be 18 words total ( 24 byte message)"
268 raise NotImplementedError
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/protocols/gps/nmea.py ('k') | third_party/twisted_8_1/twisted/protocols/htb.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698