def update_plot(self): plot_labels = [] plots = [] self.plot_data.set_data('t', self.time) # Remove any stale plots that got removed from the dictionary for each in self.plot_data.list_data(): if each not in [str(a) for a in self.CN0_dict.keys()] and each != 't': try: self.plot_data.del_data(each) self.plot.delplot(each) except KeyError: pass for k, cno_array in self.CN0_dict.iteritems(): key = str(k) # set plot data and create plot for any selected for display if ((self.show_l2 and int(k[0]) in L2_CODES) or (self.show_l1 and int(k[0]) in L1_CODES)): self.plot_data.set_data(key, cno_array) if key not in self.plot.plots.keys(): pl = self.plot.plot(('t', key), type='line', color=get_color(k), name=key) else: pl = self.plot.plots[key] # if channel is still active: plots.append(pl) plot_labels.append('Ch %02d (PRN%02d (%s))' % (k[2], k[1], code_to_str(k[0]))) # Remove plot data and plots not selected else: if key in self.plot_data.list_data(): self.plot_data.del_data(key) if key in self.plot.plots.keys(): self.plot.delplot(key) plots = dict(zip(plot_labels, plots)) self.plot.legend.plots = plots
def update_obs(self): self._obs_table_list = [ ('{} ({})'.format(svid[0], code_to_str(svid[1])), ) + obs for svid, obs in sorted(self.obs.items()) if getattr(self, 'show_{}'.format(svid[1])) ] for code in SUPPORTED_CODES: setattr(self, 'count_{}'.format(code), len([key for key in self.obs.keys() if key[1] == code]))
def get_label(key, extra): code, sat, ch = key lbl = 'Ch {ch:02d}: {code} '.format(ch=ch, code=code_to_str(code)) if code_is_gps(code): lbl += 'PRN {sat:02d}'.format(sat=sat) elif code_is_glo(code): lbl += 'FCN {sat:0=+3d}'.format(sat=sat) if sat in extra: lbl += ' Slot: {slot:02d}'.format(slot=extra[sat]) return lbl
def update_obs(self, obs_update): self.traits_obs_count = len(obs_update) self.traits_obs_table_list = [ ('{} ({})'.format(svid[0], code_to_str(svid[1])),) + obs for svid, obs in sorted(obs_update.items()) if getattr(self, 'show_{}'.format(svid[1]), True) ] for code in SUPPORTED_CODES: setattr(self, 'count_{}'.format(code), len([key for key in obs_update.keys() if key[1] == code])) if getattr(self, 'count_{}'.format(code)) != 0 and code not in self.received_codes: self.received_codes.append(code)
def trait_view(self, view): info = HGroup( Spring(width=4, springy=False), Item( '', label='Week:', emphasized=True, tooltip='GPS Week Number (since 1980'), Item('gps_week', style='readonly', show_label=False), Item( '', label='TOW:', emphasized=True, tooltip='GPS milliseconds in week'), Item( 'gps_tow', style='readonly', show_label=False, format_str='%.3f'), Item( '', label='Total obs:', emphasized=True, tooltip='Total observation count'), Item('obs_count', style='readonly', show_label=False), ) for code in SUPPORTED_CODES: code_str = code_to_str(code) info.content.append( Item( '', label='{}:'.format(code_str), emphasized=True, tooltip='{} observation count'.format(code_str))) info.content.append( Item( 'count_{}'.format(code), style='readonly', show_label=False)) return View( VGroup( info, CodeFiltered.get_filter_group(), HGroup( Item( '_obs_table_list', style='readonly', editor=TabularEditor(adapter=SimpleAdapter()), show_label=False), ), label=self.name, show_border=True))
def get_filter_group(): ''' Return horizontal tick box group. ''' hgroup = HGroup() for code in SUPPORTED_CODES: hgroup.content.append(Spring(width=8, springy=False)) hgroup.content.append( Item('show_{}'.format(code), label="{}:".format(code_to_str(code)))) return hgroup
def update_obs(self, obs_update): self.traits_obs_count = len(obs_update) self.traits_obs_table_list = [ ('{} ({})'.format(svid[0], code_to_str(svid[1])), ) + obs for svid, obs in sorted(obs_update.items()) if getattr(self, 'show_{}'.format(svid[1]), True) ] for code in SUPPORTED_CODES: setattr(self, 'count_{}'.format(code), len([key for key in obs_update.keys() if key[1] == code])) if getattr(self, 'count_{}'.format( code)) != 0 and code not in self.received_codes: self.received_codes.append(code)
def get_filter_group(): ''' Return horizontal tick box group. ''' hgroup = HGroup() for code in SUPPORTED_CODES: hgroup.content.append(Spring(width=8, springy=False)) hgroup.content.append( Item( 'show_{}'.format(code), label="{}:".format(code_to_str(code)))) return hgroup
def update_plot(self): self.cn0_history.append([s.cn0 for s in self.states]) self.cn0_history = self.cn0_history[-1000:] chans = np.transpose(self.cn0_history[-NUM_POINTS:]) plot_labels = [] for n in range(self.n_channels): self.plot_data.set_data('ch' + str(n), chans[n]) if self.states[n].state == 0: plot_labels.append('Ch %02d (Disabled)' % n) else: plot_labels.append('Ch %02d (PRN%02d (%s))' % (n, self.states[n].prn, code_to_str(self.states[n].code))) plots = dict(zip(plot_labels, self.plots)) self.plot.legend.plots = plots
def get_filter_group(): ''' Return horizontal tick box group. ''' hgroup = HGroup() for prefix, code_list in sorted(GUI_CODES.items(), key=lambda x: x[1][0] if x[0] != 'SBAS' else 100): vgroup = VGroup() for code in code_list: vgroup.content.append( Item( 'show_{}'.format(code), label="{}:".format(code_to_str(code)), visible_when="{} in received_codes".format(code))) hgroup.content.append(vgroup) return hgroup
def get_label(key, extra): code, sat, ch = key lbl = 'Ch {ch:02d}: {code} '.format(ch=ch, code=code_to_str(code)) if code_is_glo(code): lbl += 'F{sat:0=+3d}'.format(sat=sat) if ch in extra: lbl += ' R{slot:02d}'.format(slot=extra[ch]) elif code_is_sbas(code): lbl += 'S{sat:3d}'.format(sat=sat) elif code_is_bds2(code): lbl += 'C{sat:02d}'.format(sat=sat) elif code_is_qzss(code): lbl += 'J{sat:3d}'.format(sat=sat) else: lbl += 'G{sat:02d}'.format(sat=sat) return lbl
def update_plot(self): plot_labels = [] plots = [] self.plot_data.set_data('t', self.time) # Remove any stale plots that got removed from the dictionary for each in self.plot_data.list_data(): if each not in [str(a) for a in self.CN0_dict.keys()] and each != 't': try: self.plot_data.del_data(each) self.plot.delplot(each) except KeyError: pass for k, cno_array in self.CN0_dict.items(): if int(k[0]) not in SUPPORTED_CODES: continue key = str(k) # set plot data and create plot for any selected for display if (getattr(self, 'show_{}'.format(int(k[0])))): self.plot_data.set_data(key, cno_array) if key not in self.plot.plots.keys(): pl = self.plot.plot(('t', key), type='line', color=get_color(k), name=key) else: pl = self.plot.plots[key] # if channel is still active: if cno_array[-1] != 0: plots.append(pl) svid_label = 'FCN' if code_is_glo(int(k[0])) else 'PRN' plot_labels.append( 'Ch %02d (%s%02d (%s))' % (k[2], svid_label, k[1], code_to_str(k[0]))) # Remove plot data and plots not selected else: if key in self.plot_data.list_data(): self.plot_data.del_data(key) if key in self.plot.plots.keys(): self.plot.delplot(key) plots = dict(zip(plot_labels, plots)) self.plot.legend.plots = plots
def get_label(key, extra): code, sat = key lbl = '{code} '.format(code=code_to_str(code)) if code_is_glo(code): lbl += 'F{sat:0=+3d}'.format(sat=sat) if sat in extra: lbl += ' R{slot:02d}'.format(slot=extra[sat]) elif code_is_sbas(code): lbl += 'S{sat:3d}'.format(sat=sat) elif code_is_bds(code): lbl += 'C{sat:02d}'.format(sat=sat) elif code_is_qzss(code): lbl += 'J{sat:3d}'.format(sat=sat) elif code_is_galileo(code): lbl += 'E{sat:02d}'.format(sat=sat) else: lbl += 'G{sat:02d}'.format(sat=sat) return lbl
def obs_packed_callback(self, sbp_msg, **metadata): if (sbp_msg.sender is not None and (self.relay ^ (sbp_msg.sender == 0))): return tow = sbp_msg.header.t.tow wn = sbp_msg.header.t.wn seq = sbp_msg.header.n_obs tow = float(tow) / 1000.0 total = seq >> 4 count = seq & ((1 << 4) - 1) # Confirm this packet is good. # Assumes no out-of-order packets if count == 0: self.old_tow = self.gps_tow self.gps_tow = tow self.gps_week = wn self.prev_obs_total = total self.prev_obs_count = 0 self.old_cp = self.new_cp self.new_cp = {} self.obs = {} elif self.gps_tow != tow or\ self.gps_week != wn or\ self.prev_obs_count + 1 != count or\ self.prev_obs_total != total: print "We dropped a packet. Skipping this observation sequence" self.prev_obs_count = -1 return else: self.prev_obs_count = count # Save this packet # See sbp_piksi.h for format for o in sbp_msg.obs: # Handle all the message specific stuff prn = o.sid.sat flags = 0 msdopp = 0 # Old PRN values had to add one for GPS if (code_is_gps(o.sid.code) and sbp_msg.msg_type in [ SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B, SBP_MSG_OBS_DEP_C ]): prn += 1 prn = '{} ({})'.format(prn, code_to_str(o.sid.code)) # DEP_B and DEP_A obs had different pseudorange scaling if sbp_msg.msg_type in [SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B]: divisor = 1e2 else: divisor = 5e1 if sbp_msg.msg_type not in [ SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B, SBP_MSG_OBS_DEP_C ]: flags = o.flags msdopp = float(o.D.i) + float(o.D.f) / (1 << 8) self.gps_tow += sbp_msg.header.t.ns_residual * 1e-9 try: ocp = self.old_cp[prn] except: ocp = 0 cp = float(o.L.i) + float(o.L.f) / (1 << 8) # Compute time difference of carrier phase for display, but only if carrier phase is valid if ocp != 0 and ((sbp_msg.msg_type in [ SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B, SBP_MSG_OBS_DEP_C ]) or (flags & 0x3) == 0x3): # Doppler per RINEX has opposite sign direction to carrier phase if self.gps_tow != self.old_tow: cpdopp = (ocp - cp) / float(self.gps_tow - self.old_tow) else: print "Received two complete observation sets with identical TOW" cpdopp = 0 # Older messages had flipped sign carrier phase values if sbp_msg.msg_type in [SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B]: cpdopp = -cpdopp else: cpdopp = 0 # Save carrier phase value, but only if value is valid if (sbp_msg.msg_type in [ SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B, SBP_MSG_OBS_DEP_C ]) or (flags & 0x3) == 0x3: self.new_cp[prn] = cp flags_str = "0x{:04X} = ".format(flags) # Add some indicators to help understand the flags values # Bit 0 is Pseudorange valid if (flags & 0x01): flags_str += "PR " # Bit 1 is Carrier phase valid if (flags & 0x02): flags_str += "CP " # Bit 2 is Half-cycle ambiguity if (flags & 0x04): flags_str += "1/2C " # Bit 3 is Measured Doppler Valid if (flags & 0x08): flags_str += "MD " pr_str = "{:11.2f}".format(float(o.P) / divisor) cp_str = "{:13.2f}".format(cp) cn0_str = "{:2.1f}".format(float(o.cn0) / 4) msdopp_str = "{:9.2f}".format(msdopp) cpdopp_str = "{:9.2f}".format(cpdopp) lock_str = "{:5d}".format(o.lock) # Sets invalid values to zero if sbp_msg.msg_type not in [ SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B, SBP_MSG_OBS_DEP_C ]: if not (flags & 0x01): pr_str = EMPTY_STR if not (flags & 0x02): cp_str = EMPTY_STR if not (flags & 0x08): msdopp_str = EMPTY_STR if (cpdopp == 0): cpdopp_str = EMPTY_STR self.obs[prn] = (pr_str, cp_str, cn0_str, msdopp_str, cpdopp_str, lock_str, flags_str) if (count == total - 1): self.t = datetime.datetime(1980, 1, 6) + \ datetime.timedelta(weeks=self.gps_week) + \ datetime.timedelta(seconds=self.gps_tow) return
def trait_view(self, view): info = HGroup(Spring(width=4, springy=False, height=-1), Item('Label', label='Week:', style='readonly', emphasized=True, width=-1, padding=-1, height=-1, style_sheet='*{font-size:1px}', tooltip='GPS Week Number (since 1980'), Item('traits_gps_week', style='readonly', show_label=False), Item('Label', label=' TOW:', style='readonly', width=-1, padding=-1, height=-1, style_sheet='*{font-size:1px}', emphasized=True, tooltip='GPS milliseconds in week'), Item('traits_gps_tow', style='readonly', show_label=False, height=-1, format_str='%.3f'), Item('Label', label=' Total:', style='readonly', emphasized=True, width=-1, height=-1, padding=-1, style_sheet='*{font-size:1px}', tooltip='Total observation count'), Item('traits_obs_count', style='readonly', show_label=False), padding=0, springy=False) filters = HGroup(padding=0, springy=False) for prefix, code_list in sorted(GUI_CODES.items(), key=lambda x: x[1][0] if x[0] != 'SBAS' else 100): vgroup1 = VGroup( ) # two groups are needed to combat silly spacing in Traitsui vgroup2 = VGroup() for code in code_list: code_str = code_to_str(code) vgroup1.content.append( Item('count_{}'.format(code), label='{}:'.format(code_str), style='readonly', tooltip='{} observation count'.format(code_str), visible_when="{} in received_codes".format(code))) vgroup2.content.append( UItem( 'show_{}'.format(code), tooltip='show {} observations'.format(code_str), visible_when="{} in received_codes".format(code), height=-16 # this make GUI align better ), ) filters.content.append(vgroup1) filters.content.append(vgroup2) return View( VGroup(info, filters, Item('traits_obs_table_list', style='readonly', editor=TabularEditor(adapter=SimpleAdapter()), show_label=False), label=self.name, padding=0, show_border=True))
def obs_packed_callback(self, sbp_msg, **metadata): if (sbp_msg.sender is not None and (self.relay ^ (sbp_msg.sender == 0))): return tow = sbp_msg.header.t.tow wn = sbp_msg.header.t.wn seq = sbp_msg.header.n_obs tow = float(tow) / 1000.0 total = seq >> 4 count = seq & ((1 << 4) - 1) # Confirm this packet is good. # Assumes no out-of-order packets if count == 0: self.old_tow = self.gps_tow self.gps_tow = tow self.gps_week = wn self.prev_obs_total = total self.prev_obs_count = 0 self.old_obs = copy.deepcopy(self.obs) self.obs = {} elif self.gps_tow != tow or\ self.gps_week != wn or\ self.prev_obs_count + 1 != count or\ self.prev_obs_total != total: print "We dropped a packet. Skipping this observation sequence" self.prev_obs_count = -1 return else: self.prev_obs_count = count # Save this packet # See sbp_piksi.h for format for o in sbp_msg.obs: prn = o.sid.sat # compute time difference of carrier phase for display cp = float(o.L.i) + float(o.L.f) / (1 << 8) if o.sid.code == 0 or o.sid.code == 1: prn += 1 prn = '{} ({})'.format(prn, code_to_str(o.sid.code)) if sbp_msg.msg_type == SBP_MSG_OBS_DEP_A or\ sbp_msg.msg_type == SBP_MSG_OBS_DEP_B: divisor = 1e2 else: divisor = 5e1 try: ocp = self.old_obs[prn][1] except: ocp = 0 cf = (cp - ocp) / (self.gps_tow - self.old_tow) self.obs[prn] = (float(o.P) / divisor, float(o.L.i) + float(o.L.f) / (1 << 8), float(o.cn0) / 4, cf) if (count == total - 1): self.t = datetime.datetime(1980, 1, 6) + \ datetime.timedelta(weeks=self.gps_week) + \ datetime.timedelta(seconds=self.gps_tow) self.update_obs() self.rinex_save() return
def trait_view(self, view): info = HGroup( Spring(width=4, springy=False, height=-1), Item( 'Label', label='Week:', style='readonly', emphasized=True, width=-1, padding=-1, height=-1, style_sheet='*{font-size:1px}', tooltip='GPS Week Number (since 1980'), Item('traits_gps_week', style='readonly', show_label=False), Item( 'Label', label=' TOW:', style='readonly', width=-1, padding=-1, height=-1, style_sheet='*{font-size:1px}', emphasized=True, tooltip='GPS milliseconds in week'), Item( 'traits_gps_tow', style='readonly', show_label=False, height=-1, format_str='%.3f'), Item( 'Label', label=' Total:', style='readonly', emphasized=True, width=-1, height=-1, padding=-1, style_sheet='*{font-size:1px}', tooltip='Total observation count'), Item('traits_obs_count', style='readonly', show_label=False), padding=0, springy=False ) filters = HGroup(padding=0, springy=False) for prefix, code_list in sorted( GUI_CODES.items(), key=lambda x: x[1][0] if x[0] != 'SBAS' else 100): vgroup1 = VGroup() # two groups are needed to combat silly spacing in Traitsui vgroup2 = VGroup() for code in code_list: code_str = code_to_str(code) vgroup1.content.append( Item('count_{}'.format(code), label='{}:'.format(code_str), style='readonly', tooltip='{} observation count'.format(code_str), visible_when="{} in received_codes".format(code) ) ) vgroup2.content.append( UItem( 'show_{}'.format(code), tooltip='show {} observations'.format(code_str), visible_when="{} in received_codes".format(code), height=-16 # this make GUI align better ), ) filters.content.append(vgroup1) filters.content.append(vgroup2) return View( VGroup( info, filters, Item( 'traits_obs_table_list', style='readonly', editor=TabularEditor(adapter=SimpleAdapter()), show_label=False), label=self.name, padding=0, show_border=True))
def obs_packed_callback(self, sbp_msg, **metadata): if (sbp_msg.sender is not None and (self.relay ^ (sbp_msg.sender == 0))): return tow = sbp_msg.header.t.tow wn = sbp_msg.header.t.wn seq = sbp_msg.header.n_obs tow = float(tow) / 1000.0 total = seq >> 4 count = seq & ((1 << 4) - 1) # Confirm this packet is good. # Assumes no out-of-order packets if count == 0: self.old_tow = self.gps_tow self.gps_tow = tow self.gps_week = wn self.prev_obs_total = total self.prev_obs_count = 0 self.old_cp = self.new_cp self.new_cp = {} self.obs = {} elif self.gps_tow != tow or\ self.gps_week != wn or\ self.prev_obs_count + 1 != count or\ self.prev_obs_total != total: print "We dropped a packet. Skipping this observation sequence" self.prev_obs_count = -1 return else: self.prev_obs_count = count # Save this packet # See sbp_piksi.h for format for o in sbp_msg.obs: # Handle all the message specific stuff prn = o.sid.sat flags = 0 msdopp = 0 # Old PRN values had to add one for GPS if (code_is_gps(o.sid.code) and sbp_msg.msg_type in [SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B, SBP_MSG_OBS_DEP_C]): prn += 1 prn = '{} ({})'.format(prn, code_to_str(o.sid.code)) # DEP_B and DEP_A obs had different pseudorange scaling if sbp_msg.msg_type in [SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B] : divisor = 1e2 else: divisor = 5e1 if sbp_msg.msg_type not in [SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B, SBP_MSG_OBS_DEP_C]: flags = o.flags msdopp = float(o.D.i) + float(o.D.f) / (1 << 8) self.gps_tow += sbp_msg.header.t.ns * 1e-9 try: ocp = self.old_cp[prn] except: ocp = 0 cp = float(o.L.i) + float(o.L.f) / (1 << 8) # Compute time difference of carrier phase for display, but only if carrier phase is valid if ocp != 0 and ((sbp_msg.msg_type in [SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B, SBP_MSG_OBS_DEP_C]) or (flags & 0x3) == 0x3): # Doppler per RINEX has opposite sign direction to carrier phase cpdopp = (ocp - cp) / float(self.gps_tow - self.old_tow) # Older messages had flipped sign carrier phase values if sbp_msg.msg_type in [SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B]: cpdopp = -cpdopp else: cpdopp = 0 # Save carrier phase value, but only if value is valid if (sbp_msg.msg_type in [SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B, SBP_MSG_OBS_DEP_C]) or (flags & 0x3) == 0x3: self.new_cp[prn] = cp flags_str = "0x{:04X} = ".format(flags) # Add some indicators to help understand the flags values # Bit 0 is Pseudorange valid if (flags & 0x01): flags_str += "PR " # Bit 1 is Carrier phase valid if (flags & 0x02): flags_str += "CP " # Bit 2 is Half-cycle ambiguity if (flags & 0x04): flags_str += "1/2C " # Bit 3 is Measured Doppler Valid if (flags & 0x08): flags_str += "MD " pr_str = "{:11.2f}".format(float(o.P) / divisor) cp_str = "{:13.2f}".format(cp) cn0_str = "{:2.1f}".format(float(o.cn0) / 4) msdopp_str = "{:9.2f}".format(msdopp) cpdopp_str = "{:9.2f}".format(cpdopp) lock_str = "{:5d}".format(o.lock) # Sets invalid values to zero if sbp_msg.msg_type not in [SBP_MSG_OBS_DEP_A, SBP_MSG_OBS_DEP_B, SBP_MSG_OBS_DEP_C]: if not (flags & 0x01): pr_str = EMPTY_STR if not (flags & 0x02): cp_str = EMPTY_STR if not (flags & 0x08): msdopp_str = EMPTY_STR if (cpdopp == 0): cpdopp_str = EMPTY_STR self.obs[prn] = (pr_str, cp_str, cn0_str, msdopp_str, cpdopp_str, lock_str, flags_str) if (count == total - 1): self.t = datetime.datetime(1980, 1, 6) + \ datetime.timedelta(weeks=self.gps_week) + \ datetime.timedelta(seconds=self.gps_tow) self.update_obs() return