📄 gpsprof
字号:
def __init__(self): self.stats = [] def gather(self, session): self.stats.append(copy.copy(session.timings)) if session.timings.sentence_tag not in self.sentences: self.sentences.append(session.timings.sentence_tag) return True def header(self, session): res = "# Split latency data, %s, %s, %dN%d, cycle %ds\n#" % \ (title, session.gps_id, session.baudrate, session.stopbits, session.cycle) for s in splitplot.sentences: res += "%8s\t" % s for hn in ("T1", "D1", "W", "E2", "T2", "D2", "length"): res += "%8s\t" % hn res += "tag\n# " for s in tuple(splitplot.sentences) + ("T1", "D1", "W", "E2", "T2", "D2", "length"): res += "---------\t" return res + "--------\n" def data(self, session): res = "" for timings in self.stats: if timings.sentence_time: e1 = timings.d_xmit_time else: e1 = 0 for s in splitplot.sentences: if s == timings.sentence_tag: res += "%2.6f\t" % e1 else: res += "- \t" res += "%2.6f\t%2.6f\t%2.6f\t%2.6f\t%2.6f\t%2.6f\t%8d\t# %s\n" \ % (timings.d_recv_time, timings.d_decode_time, timings.poll_time, timings.emit_time, timings.c_recv_time, timings.c_decode_time, timings.sentence_length, timings.sentence_tag) return res def plot(self, title, session): fixed = '''set autoscaleset key belowset key title "Filtered latency data, %s, %s, %dN%d, cycle %ds"plot \\ "-" using 0:%d title "D2 = Client decode time" with impulses, \\ "-" using 0:%d title "T2 = TCP/IP latency" with impulses, \\ "-" using 0:%d title "E2 = Daemon encode time" with impulses, \\ "-" using 0:%d title "W = Poll wait time" with impulses, \\ "-" using 0:%d title "D1 = Daemon decode time" with impulses, \\ "-" using 0:%d title "T1 = RS3232 time" with impulses, \\''' sc = len(splitplot.sentences) fmt = fixed % (title, session.gps_id, session.baudrate, session.stopbits, session.cycle, sc+6, sc+5, sc+4, sc+3, sc+2, sc+1) for i in range(sc): fmt += ' "-" using 0:%d title "%s" with impulses, \\\n' % \ (i+1, self.sentences[i]) res = fmt[:-4] + "\n" res += self.header(session) for dummy in range(sc+6): res += self.data(session) + "e\n" return resclass cycle: "Send-cycle analysis." name = "cycle" def __init__(self): self.stats = [] def gather(self, session): self.stats.append(copy.copy(session.timings)) return True def plot(self, title, session): msg = "" def roundoff(n): # Round a time to hundredths of a second return round(n*100) / 100.0 intervals = {} last_seen = {} for timing in self.stats: # Throw out everything but the leader in each GSV group if timing.sentence_tag[-3:] == "GSV" and last_command[-3:] == "GSV": continue last_command = timing.sentence_tag # Record timings received = timing.d_received() if not timing.sentence_tag in intervals: intervals[timing.sentence_tag] = [] if timing.sentence_tag in last_seen: intervals[timing.sentence_tag].append(roundoff(received - last_seen[timing.sentence_tag])) last_seen[timing.sentence_tag] = received # Step three: get command frequencies and the basic send cycle time frequencies = {} for (key, interval_list) in intervals.items(): frequencies[key] = {} for interval in interval_list: frequencies[key][interval] = frequencies[key].get(interval, 0) + 1 # filter out noise for key in frequencies: distribution = frequencies[key] for interval in distribution.keys(): if distribution[interval] < 2: del distribution[interval] cycles = {} for key in frequencies: distribution = frequencies[key] if len(frequencies[key].values()) == 1: # The value is uniqe after filtering cycles[key] = distribution.keys()[0] else: # Compute the mode maxfreq = 0 for (interval, frequency) in distribution.items(): if distribution[interval] > maxfreq: cycles[key] = interval maxfreq = distribution[interval] msg += "Cycle report %s, %s, %dN%d, cycle %ds" % \ (title, session.gps_id, session.baudrate, session.stopbits, session.cycle) msg += "The sentence set emitted by this GPS is: %s\n" % " ".join(intervals.keys()) for key in cycles: if len(frequencies[key].values()) == 1: if cycles[key] == 1: msg += "%s: is emitted once a second.\n" % key else: msg += "%s: is emitted once every %d seconds.\n" % (key, cycles[key]) else: if cycles[key] == 1: msg += "%s: is probably emitted once a second.\n" % key else: msg += "%s: is probably emitted once every %d seconds.\n" % (key, cycles[key]) sendcycle = min(*cycles.values()) if sendcycle == 1: msg += "Send cycle is once per second.\n" else: msg += "Send cycle is once per %d seconds.\n" % sendcycle return msgformatters = (spaceplot, uninstrumented, rawplot, splitplot, cycle)def plotframe(await, fname, speed, threshold, title): "Return a string containing a GNUplot script " if fname: for formatter in formatters: if formatter.name == fname: plotter = formatter() break else: sys.stderr.write("gpsprof: no such formatter.\n") sys.exit(1) try: session = gps.gps() except socket.error: sys.stderr.write("gpsprof: gpsd unreachable.\n") sys.exit(1) try: if speed: session.query("b=%d\n" % speed) if session.baudrate != speed: sys.stderr.write("gpsprof: baud rate change failed.\n") session.query("w+bci\n") if formatter not in (spaceplot, uninstrumented): session.query("z+\n") #session.set_raw_hook(lambda x: sys.stderr.write(`x`+"\n")) baton = Baton("gpsprof: looking for fix", "done") countdown = await basetime = time.time() while countdown > 0: if session.poll() == None: sys.stderr.write("gpsprof: gpsd has vanished.\n") sys.exit(1) baton.twirl() if session.fix.mode <= gps.MODE_NO_FIX: continue if countdown == await: sys.stderr.write("first fix in %.2fsec, gathering samples..." % (time.time()-basetime,)) # We can get some funky artifacts at start of session # apparently due to RS232 buffering effects. Ignore # them. if threshold and session.timings.c_decode_time > session.cycle * threshold: continue if plotter.gather(session): countdown -= 1 baton.end() finally: session.query("w-z-\n") command = plotter.plot(title, session) del session return commandif __name__ == '__main__': try: (options, arguments) = getopt.getopt(sys.argv[1:], "f:hm:n:s:t:") formatter = "space" raw = False speed = 0 title = time.ctime() threshold = 0 await = 100 for (switch, val) in options: if (switch == '-f'): formatter = val elif (switch == '-m'): threshold = int(val) elif (switch == '-n'): await = int(val) elif (switch == '-s'): speed = int(val) elif (switch == '-t'): title = val elif (switch == '-h'): sys.stderr.write(\ "usage: gpsprof [-h] [-m threshold] [-n samplecount] \n" + "\t[-f {" + "|".join(map(lambda x: x.name, formatters)) + "}] [-s speed] [-t title]\n") sys.exit(0) sys.stdout.write(plotframe(await,formatter,speed,threshold,title)) except KeyboardInterrupt: pass
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -