def _start_fired(self): """ Handle start udp broadcast button. Registers callbacks on self.link for each of the self.msgs If self.msgs is None, it registers one generic callback for all messages """ self.running = True try: self.func = UdpLogger(self.ip_ad, self.port) self.link.add_callback(self.func, self.msgs) except: import traceback print traceback.format_exc()
def main(): args = get_args() address = args.address[0] udp_port = args.udp_port[0] with PySerialDriver(args.serial_port[0], args.baud[0]) as driver: with Handler(driver.read, driver.write) as handler: with UdpLogger(address, udp_port) as udp: handler.add_callback(udp) try: while True: time.sleep(0.1) except KeyboardInterrupt: pass
def main(): """Simple command line interface for running the udp bridge to forward observation messages """ args = get_args() port = int(args.udp_port[0]) address = args.address[0] with PySerialDriver(args.serial_port[0], args.baud[0]) as driver: with Handler(Framer(driver.read, driver.write)) as handler: with UdpLogger(address, port) as udp: handler.add_callback(udp, OBS_MSGS) # Note, we may want to send the ephemeris message in the future # but the message is too big for MAVProxy right now try: while True: time.sleep(0.1) except KeyboardInterrupt: pass
class SbpRelayView(HasTraits): """ UDP Relay view- Class allows user to specify port, IP address, and message set to relay over UDP """ running = Bool(False) configured = Bool(False) broadcasting = Bool(False) msg_enum = Enum('Observations', 'All') ip_ad = String(DEFAULT_UDP_ADDRESS) port = Int(DEFAULT_UDP_PORT) information = String( 'UDP Streaming\n\nBroadcast SBP information received by' ' the console to other machines or processes over UDP. With the \'Observations\'' ' radio button selected, the console will broadcast the necessary information' ' for a rover Piksi to acheive an RTK solution.' '\n\nThis can be used to stream observations to a remote Piksi through' ' aircraft telemetry via ground control software such as MAVProxy or' ' Mission Planner.') http_information = String( 'Skylark - Experimental Piksi Networking\n\n' "Skylark is Swift Navigation's Internet service for connecting Piksi receivers without the use of a radio. To receive GPS observations from the closest nearby Piksi base station (within 5km), click Connect to Skylark.\n\n" ) start = Button(label='Start', toggle=True, width=32) stop = Button(label='Stop', toggle=True, width=32) connected_rover = Bool(False) connect_rover = Button(label='Connect to Skylark', toggle=True, width=32) disconnect_rover = Button(label='Disconnect from Skylark', toggle=True, width=32) base_pragma = String() rover_pragma = String() base_device_uid = String() rover_device_uid = String() toggle = True view = View( VGroup( spring, HGroup( VGroup( Item('running', show_label=True, style='readonly', visible_when='running'), Item('msg_enum', label="Messages to broadcast", style='custom', enabled_when='not running'), Item('ip_ad', label='IP Address', enabled_when='not running'), Item('port', label="Port", enabled_when='not running'), HGroup( spring, UItem('start', enabled_when='not running', show_label=False), UItem('stop', enabled_when='running', show_label=False), spring)), VGroup( Item('information', label="Notes", height=10, editor=MultilineTextEditor( TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ), ), spring, HGroup( VGroup( HGroup( spring, UItem('connect_rover', enabled_when='not connected_rover', show_label=False), UItem('disconnect_rover', enabled_when='connected_rover', show_label=False), spring), HGroup(spring, Item('base_pragma', label='Base option '), Item('base_device_uid', label='Base device '), spring), HGroup(spring, Item('rover_pragma', label='Rover option'), Item('rover_device_uid', label='Rover device'), spring), ), VGroup( Item('http_information', label="Notes", height=10, editor=MultilineTextEditor( TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ), ), spring)) def __init__(self, link, device_uid=None, base=DEFAULT_BASE, whitelist=None): """ Traits tab with UI for UDP broadcast of SBP. Parameters ---------- link : sbp.client.handler.Handler Link for SBP transfer to/from Piksi. device_uid : str Piksi Device UUID (defaults to None) base : str HTTP endpoint whitelist : [int] | None Piksi Device UUID (defaults to None) """ self.link = link self.http = HTTPDriver(None, base) self.net_link = None self.fwd = None self.func = None # Whitelist used for UDP broadcast view self.msgs = OBS_MSGS # register a callback when the msg_enum trait changes self.on_trait_change(self.update_msgs, 'msg_enum') # Whitelist used for Skylark broadcasting self.whitelist = whitelist self.device_uid = None self.python_console_cmds = {'update': self} def update_msgs(self): """Updates the instance variable msgs which store the msgs that we will send over UDP. """ if self.msg_enum == 'Observations': self.msgs = OBS_MSGS elif self.msg_enum == 'All': self.msgs = [None] else: raise NotImplementedError def set_route(self, serial_id, channel=CHANNEL_UUID): """Sets serial_id hash for HTTP headers. Parameters ---------- serial_id : int Piksi device ID channel : str UUID namespace for device UUID """ device_uid = str(get_uuid(channel, serial_id)) self.device_uid = device_uid if self.http: self.http.device_uid = device_uid def _prompt_networking_error(self, text): """Nonblocking prompt for a networking error. Parameters ---------- text : str Helpful error message for the user """ prompt = CallbackPrompt(title="Networking Error", actions=[close_button]) prompt.text = text prompt.run(block=False) def _prompt_setting_error(self, text): """Nonblocking prompt for a device setting error. Parameters ---------- text : str Helpful error message for the user """ prompt = CallbackPrompt(title="Setting Error", actions=[close_button]) prompt.text = text prompt.run(block=False) def _retry_read(self): """Retry read connections. Intended to be called by _connect_rover_fired. """ i = 0 repeats = 5 _rover_pragma = self.rover_pragma _rover_device_uid = self.rover_device_uid or self.device_uid while self.http and not self.http.connect_read( device_uid=_rover_device_uid, pragma=_rover_pragma): print "Attempting to read observation from Skylark..." time.sleep(0.1) i += 1 if i >= repeats: msg = ( "\nUnable to receive observations from Skylark!\n\n" "Please check that:\n" " - you have a network connection\n" " - your Piksi has a single-point position\n" " - a Skylark-connected Piksi receiver \n is nearby (within 5km)" ) self._prompt_networking_error(msg) self.http.read_close() return print "Connected as a rover!" with Handler(Framer(self.http.read, self.http.write)) as net_link: self.net_link = net_link self.fwd = Forwarder(net_link, swriter(self.link)) self.fwd.start() while True: time.sleep(1) if not net_link.is_alive(): sys.stderr.write( "Network observation stream disconnected!") break # Unless the user has initiated a reconnection, assume here that the rover # still wants to be connected, so if we break out of the handler loop, # cleanup rover connection and try reconnecting. if self.connected_rover: sys.stderr.write("Going for a networking reconnection!") self._disconnect_rover_fired() self._connect_rover_fired() def _connect_rover_fired(self): """Handle callback for HTTP rover connections. """ if not self.device_uid: msg = "\nDevice ID not found!\n\nConnection requires a valid Piksi device ID." self._prompt_setting_error(msg) return if not self.http: self._prompt_networking_error("\nNetworking disabled!") return try: _base_pragma = self.base_pragma _base_device_uid = self.base_device_uid or self.device_uid if not self.http.connect_write(self.link, self.whitelist, device_uid=_base_device_uid, pragma=_base_pragma): msg = ("\nUnable to connect to Skylark!\n\n" "Please check that you have a network connection.") self._prompt_networking_error(msg) self.http.close() self.connected_rover = False return self.connected_rover = True print "Connected as a base station!" executor = ThreadPoolExecutor(max_workers=2) executor.submit(self._retry_read) except: self.connected_rover = False import traceback print traceback.format_exc() def _disconnect_rover_fired(self): """Handle callback for HTTP rover disconnects. """ if not self.device_uid: msg = "\nDevice ID not found!\n\nConnection requires a valid Piksi device ID." self._prompt_setting_error(msg) return if not self.http: self._prompt_networking_error("\nNetworking disabled!") return try: if self.connected_rover: self.http.close() self.connected_rover = False if self.fwd and self.net_link: self.net_link.stop() except: self.connected_rover = False import traceback print traceback.format_exc() def _start_fired(self): """Handle start udp broadcast button. Registers callbacks on self.link for each of the self.msgs If self.msgs is None, it registers one generic callback for all messages. """ self.running = True try: self.func = UdpLogger(self.ip_ad, self.port) self.link.add_callback(self.func, self.msgs) except: import traceback print traceback.format_exc() def _stop_fired(self): """Handle the stop udp broadcast button. It uses the self.funcs and self.msgs to remove the callbacks that were registered when the start button was pressed. """ try: self.link.remove_callback(self.func, self.msgs) self.func.__exit__() self.func = None self.running = False except: import traceback print traceback.format_exc()
class SbpRelayView(HasTraits): """ UDP Relay view- Class allows user to specify port, IP address, and message set to relay over UDP """ running = Bool(False) configured = Bool(False) broadcasting = Bool(False) msg_enum = Enum('Observations', 'All') ip_ad = String(DEFAULT_UDP_ADDRESS) port = Int(DEFAULT_UDP_PORT) information = String( 'This tab is used to broadcast SBP information received by' ' the console to other machines or processes over UDP. With the \'Observations\'' ' radio button selected, the console will broadcast the necessary information' ' for a rover Piksi to acheive an RTK solution.' '\n\nThis tab can be used to stream observations to a remote Piksi through' ' aircraft telemetry via ground control software such as MAVProxy or' ' Mission Planner.') start = Button(label='Start', toggle=True, width=32) stop = Button(label='Stop', toggle=True, width=32) view = View( HGroup( VGroup( Item('running', show_label=True, style='readonly', visible_when='running'), Item('msg_enum', label="Messages to broadcast", style='custom', enabled_when='not running'), Item('ip_ad', label='IP Address', enabled_when='not running'), Item('port', label="Port", enabled_when='not running'), HGroup( spring, UItem('start', enabled_when='not running', show_label=False), UItem('stop', enabled_when='running', show_label=False), spring)), VGroup( Item('information', label="Notes", height=10, editor=MyTextEditor(TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ), )) def __init__(self, link): """ Traits tab with UI for UDP broadcast of SBP. Parameters ---------- link : sbp.client.handler.Handler Link for SBP transfer to/from Piksi. """ self.func = None self.msgs = OBS_MSGS # register a callback when the msg_enum trait changes self.on_trait_change(self.update_msgs, 'msg_enum') self.link = link self.python_console_cmds = {'update': self} def update_msgs(self): """ Updates the instance variable msgs which store the msgs that we will send over UDP """ if self.msg_enum == 'Observations': self.msgs = OBS_MSGS elif self.msg_enum == 'All': self.msgs = [None] else: raise NotImplementedError def _start_fired(self): """ Handle start udp broadcast button. Registers callbacks on self.link for each of the self.msgs If self.msgs is None, it registers one generic callback for all messages """ self.running = True try: self.func = UdpLogger(self.ip_ad, self.port) self.link.add_callback(self.func, self.msgs) except: import traceback print traceback.format_exc() def _stop_fired(self): """ Handle the stop udp broadcast button. It uses the self.funcs and self.msgs to remove the callbacks that were registered when the start button was pressed. """ try: self.link.remove_callback(self.func, self.msgs) self.func.__exit__() self.func = None self.running = False except: import traceback print traceback.format_exc()
class SbpRelayView(HasTraits): """ UDP Relay view- Class allows user to specify port, IP address, and message set to relay over UDP """ running = Bool(False) configured = Bool(False) broadcasting = Bool(False) msg_enum = Enum('Observations', 'All') ip_ad = String(DEFAULT_UDP_ADDRESS) port = Int(DEFAULT_UDP_PORT) information = String('This tab is used to broadcast SBP information received by' ' the console to other machines or processes over UDP. With the \'Observations\'' ' radio button selected, the console will broadcast the necessary information' ' for a rover Piksi to acheive an RTK solution.' '\n\nThis tab can be used to stream observations to a remote Piksi through' ' aircraft telemetry via ground control software such as MAVProxy or' ' Mission Planner.') start = Button(label='Start', toggle=True, width=32) stop = Button(label='Stop', toggle=True, width=32) view = View( HGroup( VGroup( Item('running', show_label=True, style='readonly', visible_when='running'), Item('msg_enum', label="Messages to broadcast", style='custom', enabled_when='not running'), Item('ip_ad', label='IP Address', enabled_when='not running'), Item('port', label="Port", enabled_when='not running'), HGroup( spring, UItem('start', enabled_when='not running', show_label=False), UItem('stop', enabled_when='running', show_label=False), spring ) ), VGroup( Item('information', label="Notes", height=10, editor=MyTextEditor(TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ), ) ) def __init__(self, link): """ Traits tab with UI for UDP broadcast of SBP. Parameters ---------- link : sbp.client.handler.Handler Link for SBP transfer to/from Piksi. """ self.func = None self.msgs = OBS_MSGS # register a callback when the msg_enum trait changes self.on_trait_change(self.update_msgs, 'msg_enum') self.link = link self.python_console_cmds = {'update': self} def update_msgs(self): """ Updates the instance variable msgs which store the msgs that we will send over UDP """ if self.msg_enum == 'Observations': self.msgs = OBS_MSGS elif self.msg_enum == 'All': self.msgs = [None] else: raise NotImplementedError def _start_fired(self): """ Handle start udp broadcast button. Registers callbacks on self.link for each of the self.msgs If self.msgs is None, it registers one generic callback for all messages """ self.running = True try: self.func = UdpLogger(self.ip_ad, self.port) self.link.add_callback(self.func, self.msgs) except: import traceback print traceback.format_exc() def _stop_fired(self): """ Handle the stop udp broadcast button. It uses the self.funcs and self.msgs to remove the callbacks that were registered when the start button was pressed. """ try: self.link.remove_callback(self.func, self.msgs) self.func.__exit__() self.func = None self.running = False except: import traceback print traceback.format_exc()
def test_udp_logger(): msg = SBP(1, 2, 3, 'abc', 4) handler = udp_handler(msg.pack()) ip, port = udp_server(handler) with UdpLogger(ip, port) as udp: udp(msg)
class SbpRelayView(HasTraits): """ UDP Relay view- Class allows user to specify port, IP address, and message set to relay over UDP """ running = Bool(False) configured = Bool(False) broadcasting = Bool(False) msg_enum = Enum('Observations', 'All') ip_ad = String(DEFAULT_UDP_ADDRESS) port = Int(DEFAULT_UDP_PORT) information = String('UDP Streaming\n\nBroadcast SBP information received by' ' the console to other machines or processes over UDP. With the \'Observations\'' ' radio button selected, the console will broadcast the necessary information' ' for a rover Piksi to acheive an RTK solution.' '\n\nThis can be used to stream observations to a remote Piksi through' ' aircraft telemetry via ground control software such as MAVProxy or' ' Mission Planner.') http_information = String('Skylark - Experimental Piksi Networking\n\n' "Skylark is Swift Navigation's Internet service for connecting Piksi receivers without the use of a radio. To receive GPS observations from the closest nearby Piksi base station (within 5km), click Connect to Skylark.\n\n") start = Button(label='Start', toggle=True, width=32) stop = Button(label='Stop', toggle=True, width=32) connected_rover = Bool(False) connect_rover = Button(label='Connect to Skylark', toggle=True, width=32) disconnect_rover = Button(label='Disconnect from Skylark', toggle=True, width=32) base_pragma = String() rover_pragma = String() toggle=True view = View( VGroup( spring, HGroup( VGroup( Item('running', show_label=True, style='readonly', visible_when='running'), Item('msg_enum', label="Messages to broadcast", style='custom', enabled_when='not running'), Item('ip_ad', label='IP Address', enabled_when='not running'), Item('port', label="Port", enabled_when='not running'), HGroup( spring, UItem('start', enabled_when='not running', show_label=False), UItem('stop', enabled_when='running', show_label=False), spring)), VGroup( Item('information', label="Notes", height=10, editor=MultilineTextEditor(TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ), ), spring, HGroup( VGroup( HGroup( spring, UItem('connect_rover', enabled_when='not connected_rover', show_label=False), UItem('disconnect_rover', enabled_when='connected_rover', show_label=False), spring), HGroup(spring, Item('base_pragma', label='Base option '), spring), HGroup(spring, Item('rover_pragma', label='Rover option'), spring),), VGroup( Item('http_information', label="Notes", height=10, editor=MultilineTextEditor(TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ), ), spring ) ) def __init__(self, link, device_uid=None, base=DEFAULT_BASE, whitelist=None): """ Traits tab with UI for UDP broadcast of SBP. Parameters ---------- link : sbp.client.handler.Handler Link for SBP transfer to/from Piksi. device_uid : str Piksi Device UUID (defaults to None) base : str HTTP endpoint whitelist : [int] | None Piksi Device UUID (defaults to None) """ self.link = link self.http = HTTPDriver(None, base) self.net_link = None self.fwd = None self.func = None # Whitelist used for UDP broadcast view self.msgs = OBS_MSGS # register a callback when the msg_enum trait changes self.on_trait_change(self.update_msgs, 'msg_enum') # Whitelist used for Skylark broadcasting self.whitelist = whitelist self.device_uid = None self.python_console_cmds = {'update': self} def update_msgs(self): """Updates the instance variable msgs which store the msgs that we will send over UDP. """ if self.msg_enum == 'Observations': self.msgs = OBS_MSGS elif self.msg_enum == 'All': self.msgs = [None] else: raise NotImplementedError def set_route(self, serial_id, channel=CHANNEL_UUID): """Sets serial_id hash for HTTP headers. Parameters ---------- serial_id : int Piksi device ID channel : str UUID namespace for device UUID """ device_uid = str(get_uuid(channel, serial_id)) self.device_uid = device_uid if self.http: self.http.device_uid = device_uid def _prompt_networking_error(self, text): """Nonblocking prompt for a networking error. Parameters ---------- text : str Helpful error message for the user """ prompt = CallbackPrompt(title="Networking Error", actions=[close_button]) prompt.text = text prompt.run(block=False) def _prompt_setting_error(self, text): """Nonblocking prompt for a device setting error. Parameters ---------- text : str Helpful error message for the user """ prompt = CallbackPrompt(title="Setting Error", actions=[close_button]) prompt.text = text prompt.run(block=False) def _retry_read(self): """Retry read connections. Intended to be called by _connect_rover_fired. """ i = 0 repeats = 5 _rover_pragma = self.rover_pragma while self.http and not self.http.connect_read(pragma=_rover_pragma): print "Attempting to read observation from Skylark..." time.sleep(0.1) i += 1 if i >= repeats: msg = ("\nUnable to receive observations from Skylark!\n\n" "Please check that:\n" " - you have a network connection\n" " - your Piksi has a single-point position\n" " - a Skylark-connected Piksi receiver \n is nearby (within 5km)") self._prompt_networking_error(msg) self.http.read_close() return print "Connected as a rover!" with Handler(Framer(self.http.read, self.http.write)) as net_link: self.net_link = net_link self.fwd = Forwarder(net_link, swriter(self.link)) self.fwd.start() while True: time.sleep(1) if not net_link.is_alive(): sys.stderr.write("Network observation stream disconnected!") break def _connect_rover_fired(self): """Handle callback for HTTP rover connections. """ if not self.device_uid: msg = "\nDevice ID not found!\n\nConnection requires a valid Piksi device ID." self._prompt_setting_error(msg) return if not self.http: self._prompt_networking_error("\nNetworking disabled!") return try: _base_pragma = self.base_pragma if not self.http.connect_write(self.link, self.whitelist, pragma=_base_pragma): msg = ("\nUnable to connect to Skylark!\n\n" "Please check that you have a network connection.") self._prompt_networking_error(msg) self.http.close() self.connected_rover = False return self.connected_rover = True print "Connected as a base station!" executor = ThreadPoolExecutor(max_workers=2) executor.submit(self._retry_read) except: self.connected_rover = False import traceback print traceback.format_exc() def _disconnect_rover_fired(self): """Handle callback for HTTP rover disconnects. """ if not self.device_uid: msg = "\nDevice ID not found!\n\nConnection requires a valid Piksi device ID." self._prompt_setting_error(msg) return if not self.http: self._prompt_networking_error("\nNetworking disabled!") return try: if self.connected_rover: self.http.close() self.connected_rover = False if self.fwd and self.net_link: self.net_link.stop() except: self.connected_rover = False import traceback print traceback.format_exc() def _start_fired(self): """Handle start udp broadcast button. Registers callbacks on self.link for each of the self.msgs If self.msgs is None, it registers one generic callback for all messages. """ self.running = True try: self.func = UdpLogger(self.ip_ad, self.port) self.link.add_callback(self.func, self.msgs) except: import traceback print traceback.format_exc() def _stop_fired(self): """Handle the stop udp broadcast button. It uses the self.funcs and self.msgs to remove the callbacks that were registered when the start button was pressed. """ try: self.link.remove_callback(self.func, self.msgs) self.func.__exit__() self.func = None self.running = False except: import traceback print traceback.format_exc()
class SbpRelayView(HasTraits): """ SBP Relay view- Class allows user to specify port, IP address, and message set to relay over UDP and to configure a skylark connection """ running = Bool(False) configured = Bool(False) broadcasting = Bool(False) msg_enum = Enum('Observations', 'All') ip_ad = String(DEFAULT_UDP_ADDRESS) port = Int(DEFAULT_UDP_PORT) information = String('UDP Streaming\n\nBroadcast SBP information received by' ' the console to other machines or processes over UDP. With the \'Observations\'' ' radio button selected, the console will broadcast the necessary information' ' for a rover Piksi to acheive an RTK solution.' '\n\nThis can be used to stream observations to a remote Piksi through' ' aircraft telemetry via ground control software such as MAVProxy or' ' Mission Planner.') http_information = String('Skylark - Experimental Piksi Networking\n\n' "Skylark is Swift Navigation's Internet service for connecting Piksi receivers without the use of a radio. To receive GPS observations from the closest nearby Piksi base station (within 5km), click Connect to Skylark.\n\n") start = Button(label='Start', toggle=True, width=32) stop = Button(label='Stop', toggle=True, width=32) connected_rover = Bool(False) connect_rover = Button(label='Connect to Skylark', toggle=True, width=32) disconnect_rover = Button(label='Disconnect from Skylark', toggle=True, width=32) skylark_url = String() base_pragma = String() rover_pragma = String() base_device_uid = String() rover_device_uid = String() toggle=True view = View( VGroup( spring, HGroup( VGroup( Item('running', show_label=True, style='readonly', visible_when='running'), Item('msg_enum', label="Messages to broadcast", style='custom', enabled_when='not running'), Item('ip_ad', label='IP Address', enabled_when='not running'), Item('port', label="Port", enabled_when='not running'), HGroup( spring, UItem('start', enabled_when='not running', show_label=False), UItem('stop', enabled_when='running', show_label=False), spring)), VGroup( Item('information', label="Notes", height=10, editor=MultilineTextEditor(TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ), ), spring, HGroup( VGroup( HGroup( spring, UItem('connect_rover', enabled_when='not connected_rover', show_label=False), UItem('disconnect_rover', enabled_when='connected_rover', show_label=False), spring), HGroup(Spring(springy=False, width=2), Item('skylark_url', enabled_when='not connected_rover', show_label=True), Spring(springy=False, width=2) ), HGroup(spring, Item('base_pragma', label='Base option '), Item('base_device_uid', label='Base device '), spring), HGroup(spring, Item('rover_pragma', label='Rover option'), Item('rover_device_uid', label='Rover device'), spring),), VGroup( Item('http_information', label="Notes", height=10, editor=MultilineTextEditor(TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ), ), spring ) ) def __init__(self, link, device_uid=None, base=DEFAULT_BASE, whitelist=None, rover_pragma='', base_pragma='', rover_uuid='', base_uuid='', connect=False, verbose=False): """ Traits tab with UI for UDP broadcast of SBP. Parameters ---------- link : sbp.client.handler.Handler Link for SBP transfer to/from Piksi. device_uid : str Piksi Device UUID (defaults to None) base : str HTTP endpoint whitelist : [int] | None Piksi Device UUID (defaults to None) """ self.link = link # Whitelist used for UDP broadcast view self.msgs = OBS_MSGS # register a callback when the msg_enum trait changes self.on_trait_change(self.update_msgs, 'msg_enum') # Whitelist used for Skylark broadcasting self.whitelist = whitelist self.device_uid = None self.python_console_cmds = {'update': self} self.rover_pragma = rover_pragma self.base_pragma = base_pragma self.rover_device_uid = rover_uuid self.base_device_uid = base_uuid self.verbose = verbose self.skylark_watchdog_thread = None self.skylark_url = base if connect: self.connect_when_uuid_received = True else: self.connect_when_uuid_received = False def update_msgs(self): """Updates the instance variable msgs which store the msgs that we will send over UDP. """ if self.msg_enum == 'Observations': self.msgs = OBS_MSGS elif self.msg_enum == 'All': self.msgs = [None] else: raise NotImplementedError def set_route(self, uuid=None, serial_id=None, channel=CHANNEL_UUID): """Sets serial_id hash for HTTP headers. Parameters ---------- uuid: str real uuid of device serial_id : int Piksi device ID channel : str UUID namespace for device UUID """ if uuid: device_uid = uuid elif serial_id: device_uid = str(get_uuid(channel, serial_id % 1000)) else: print("Improper call of set_route, either a serial number or UUID should be passed") device_uid = str(get_uuid(channel, 1234)) print(("Setting UUID to default value of {0}".format(device_uid))) self.device_uid = device_uid def _prompt_setting_error(self, text): """Nonblocking prompt for a device setting error. Parameters ---------- text : str Helpful error message for the user """ prompt = CallbackPrompt(title="Setting Error", actions=[close_button]) prompt.text = text prompt.run(block=False) def _disconnect_rover_fired(self): """Handle callback for HTTP rover disconnects. """ try: if isinstance(self.skylark_watchdog_thread, threading.Thread) and \ not self.skylark_watchdog_thread.stopped(): self.skylark_watchdog_thread.stop() else: print((("Unable to disconnect: Skylark watchdog thread " "inititalized at {0} and connected since {1} has " "already been stopped").format(self.skylark_watchdog_thread.get_init_time(), self.skylark_watchdog_thread.get_connect_time()))) self.connected_rover = False except: self.connected_rover = False import traceback print((traceback.format_exc())) def _connect_rover_fired(self): """Handle callback for HTTP rover connections. Launches an instance of skylark_watchdog_thread. """ if not self.device_uid: msg = "\nDevice ID not found!\n\nConnection requires a valid Piksi device ID." self._prompt_setting_error(msg) return try: _base_device_uid = self.base_device_uid or self.device_uid _rover_device_uid = self.rover_device_uid or self.device_uid config = SkylarkConsoleConnectConfig(self.link, self.device_uid, self.skylark_url, self.whitelist, self.rover_pragma, self.base_pragma, _rover_device_uid, _base_device_uid) self.skylark_watchdog_thread = SkylarkWatchdogThread(link=self.link, skylark_config=config, stopped_callback=self._disconnect_rover_fired, verbose=self.verbose) self.connected_rover = True self.skylark_watchdog_thread.start() except: if isinstance(self.skylark_watchdog_thread, threading.Thread) \ and self.skylark_watchdog_thread.stopped(): self.skylark_watchdog_thread.stop() self.connected_rover = False import traceback print((traceback.format_exc())) def _start_fired(self): """Handle start udp broadcast button. Registers callbacks on self.link for each of the self.msgs If self.msgs is None, it registers one generic callback for all messages. """ self.running = True try: self.func = UdpLogger(self.ip_ad, self.port) self.link.add_callback(self.func, self.msgs) except: import traceback print((traceback.format_exc())) def _stop_fired(self): """Handle the stop udp broadcast button. It uses the self.funcs and self.msgs to remove the callbacks that were registered when the start button was pressed. """ try: self.link.remove_callback(self.func, self.msgs) self.func.__exit__() self.func = None self.running = False except: import traceback print((traceback.format_exc()))
NTRIP_HOST = rospy.get_param('/ntrip_host', "rtk2go.com") NTRIP_PORT = rospy.get_param('/ntrip_port', 2101) NTRIP_MOUNT_POINT = rospy.get_param('/ntrip_mount_point', "ER_Valldoreix_1") #RADIO RADIO_PORT = rospy.get_param('/sbp_arbitrator/radio_port', "/dev/freewaveGXMT14") RADIO_BAUDRATE = rospy.get_param('/sbp_arbitrator/radio_baudrate', 115200) # UDP LOGGER UDP_ADDRESS = rospy.get_param('/sbp_arbitrator/udp_address', "192.168.8.222") UDP_PORT = rospy.get_param('/sbp_arbitrator/udp_port', 55558) freq = rospy.get_param('/sbp_arbitrator/frequency', 5) debug = rospy.get_param('/sbp_arbitrator/debug', False) # create instance of UdpLogger object udp = UdpLogger(UDP_ADDRESS, UDP_PORT) # txt files for msg logging if debug: HOME = os.getenv('HOME') now = datetime.datetime.utcnow() txt_time = now.strftime("%Y%m%d%H%M%S") ntrip_file_path = HOME + "/sbp_arb_logs/" + txt_time + "_ntrip.txt" radio_file_path = HOME + "/sbp_arb_logs/" + txt_time + "_radio.txt" arb_file_path = HOME + "/sbp_arb_logs/" + txt_time + "_arbitrator.txt" ntrip_txt_file = open(ntrip_file_path, "a") radio_txt_file = open(radio_file_path, "a") arb_txt_file = open(arb_file_path, "a") # get current year:month:day:hour
class SbpRelayView(HasTraits): """ SBP Relay view- Class allows user to specify port, IP address, and message set to relay over UDP and to configure a http connection """ running = Bool(False) _network_info = List() configured = Bool(False) broadcasting = Bool(False) msg_enum = Enum('Observations', 'All') ip_ad = String(DEFAULT_UDP_ADDRESS) port = Int(DEFAULT_UDP_PORT) information = String( 'UDP Streaming\n\nBroadcast SBP information received by' ' the console to other machines or processes over UDP. With the \'Observations\'' ' radio button selected, the console will broadcast the necessary information' ' for a rover Piksi to acheive an RTK solution.' '\n\nThis can be used to stream observations to a remote Piksi through' ' aircraft telemetry via ground control software such as MAVProxy or' ' Mission Planner.') show_networking = Bool(False) http_information = String( 'Experimental Piksi Networking\n\n' "Use this widget to connect Piksi receivers to http servers.\n\n") start = Button(label='Start', toggle=True, width=32) stop = Button(label='Stop', toggle=True, width=32) connected_rover = Bool(False) connect_rover = Button(label='Connect', toggle=True, width=32) disconnect_rover = Button(label='Disconnect', toggle=True, width=32) url = String() base_pragma = String() rover_pragma = String() base_device_uid = String() rover_device_uid = String() toggle = True network_refresh_button = SVGButton( label='Refresh Network Status', tooltip='Refresh Network Status', filename=resource_filename('console/images/fontawesome/refresh.svg'), width=16, height=16, aligment='center') cell_modem_view = Instance(CellModemView) view = View( VGroup( spring, HGroup(VGroup( Item('msg_enum', label="Messages to broadcast", style='custom', enabled_when='not running'), Item('ip_ad', label='IP Address', enabled_when='not running'), Item('port', label="Port", enabled_when='not running'), HGroup( spring, UItem('start', enabled_when='not running', show_label=False), UItem('stop', enabled_when='running', show_label=False), spring)), VGroup( Item('information', label="Notes", height=10, editor=MultilineTextEditor( TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ), visible_when='not show_networking'), spring, HGroup(VGroup( HGroup( spring, UItem('connect_rover', enabled_when='not connected_rover', show_label=False), UItem('disconnect_rover', enabled_when='connected_rover', show_label=False), spring), HGroup( Spring(springy=False, width=2), Item('url', enabled_when='not connected_rover', show_label=True), Spring(springy=False, width=2)), HGroup(spring, Item('base_pragma', label='Base option '), Item('base_device_uid', label='Base device '), spring), HGroup(spring, Item('rover_pragma', label='Rover option'), Item('rover_device_uid', label='Rover device'), spring), ), VGroup( Item('http_information', label="Notes", height=10, editor=MultilineTextEditor( TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ), visible_when='show_networking'), HGroup( Item('cell_modem_view', style='custom', show_label=False), VGroup(Item( '_network_info', style='readonly', editor=TabularEditor(adapter=SimpleNetworkAdapter()), show_label=False, ), Item('network_refresh_button', show_label=False, width=0.50), show_border=True, label="Network"), ))) def _network_callback(self, m, **metadata): txstr = sizeof_fmt(m.tx_bytes), rxstr = sizeof_fmt(m.rx_bytes) if m.interface_name.startswith( 'ppp0'): # Hack for ppp tx and rx which doesn't work txstr = "---" rxstr = "---" elif m.interface_name.startswith('lo') or m.interface_name.startswith( 'sit0'): return table_row = ((m.interface_name, ip_bytes_to_string(m.ipv4_address), ((m.flags & (1 << 6)) != 0), txstr, rxstr)) exists = False for i, each in enumerate(self._network_info): if each[0][0] == table_row[0][0]: self._network_info[i] = table_row exists = True if not exists: self._network_info.append(table_row) def __init__(self, link, show_networking=False, device_uid=None, url='', whitelist=None, rover_pragma='', base_pragma='', rover_uuid='', base_uuid='', connect=False, verbose=False): """ Traits tab with UI for UDP broadcast of SBP. Parameters ---------- link : sbp.client.handler.Handler Link for SBP transfer to/from Piksi. device_uid : str Piksi Device UUID (defaults to None) base : str HTTP endpoint whitelist : [int] | None Piksi Device UUID (defaults to None) """ self.link = link # Whitelist used for UDP broadcast view self.cell_modem_view = CellModemView(link) self.msgs = OBS_MSGS # register a callback when the msg_enum trait changes self.on_trait_change(self.update_msgs, 'msg_enum') # Whitelist used for broadcasting self.whitelist = whitelist self.device_uid = None self.python_console_cmds = {'update': self} self.rover_pragma = rover_pragma self.base_pragma = base_pragma self.rover_device_uid = rover_uuid self.base_device_uid = base_uuid self.verbose = verbose self.http_watchdog_thread = None self.url = url self.show_networking = show_networking if connect: self.connect_when_uuid_received = True else: self.connect_when_uuid_received = False self.cellmodem_interface_name = "ppp0" self.link.add_callback(self._network_callback, SBP_MSG_NETWORK_STATE_RESP) def update_msgs(self): """Updates the instance variable msgs which store the msgs that we will send over UDP. """ if self.msg_enum == 'Observations': self.msgs = OBS_MSGS elif self.msg_enum == 'All': self.msgs = [None] else: raise NotImplementedError def set_route(self, uuid=None, serial_id=None, channel=CHANNEL_UUID): """Sets serial_id hash for HTTP headers. Parameters ---------- uuid: str real uuid of device serial_id : int Piksi device ID channel : str UUID namespace for device UUID """ if uuid: device_uid = uuid elif serial_id: device_uid = str(get_uuid(channel, serial_id % 1000)) else: print( "Improper call of set_route, either a serial number or UUID should be passed" ) device_uid = str(get_uuid(channel, 1234)) print("Setting UUID to default value of {0}".format(device_uid)) self.device_uid = device_uid def _prompt_setting_error(self, text): """Nonblocking prompt for a device setting error. Parameters ---------- text : str Helpful error message for the user """ prompt = CallbackPrompt(title="Setting Error", actions=[close_button]) prompt.text = text prompt.run(block=False) def update_network_state(self): self._network_refresh_button_fired() def _network_refresh_button_fired(self): self._network_info = [] self.link(MsgNetworkStateReq()) def _disconnect_rover_fired(self): """Handle callback for HTTP rover disconnects. """ try: if (isinstance(self.http_watchdog_thread, threading.Thread) and not self.http_watchdog_thread.stopped()): self.http_watchdog_thread.stop() else: print(("Unable to disconnect: Http watchdog thread " "inititalized at {0} and connected since {1} has " "already been stopped").format( self.http_watchdog_thread.get_init_time(), self.http_watchdog_thread.get_connect_time())) self.connected_rover = False except: # noqa self.connected_rover = False import traceback print(traceback.format_exc()) def _connect_rover_fired(self): """Handle callback for HTTP rover connections. Launches an instance of http_watchdog_thread. """ if not self.device_uid: msg = "\nDevice ID not found!\n\nConnection requires a valid Piksi device ID." self._prompt_setting_error(msg) return try: _base_device_uid = self.base_device_uid or self.device_uid _rover_device_uid = self.rover_device_uid or self.device_uid config = HttpConsoleConnectConfig(self.link, self.device_uid, self.url, self.whitelist, self.rover_pragma, self.base_pragma, _rover_device_uid, _base_device_uid) self.http_watchdog_thread = HttpWatchdogThread( link=self.link, http_config=config, stopped_callback=self._disconnect_rover_fired, verbose=self.verbose) self.connected_rover = True self.http_watchdog_thread.start() except: # noqa if (isinstance(self.http_watchdog_thread, threading.Thread) and self.http_watchdog_thread.stopped()): self.http_watchdog_thread.stop() self.connected_rover = False import traceback print(traceback.format_exc()) def _start_fired(self): """Handle start udp broadcast button. Registers callbacks on self.link for each of the self.msgs If self.msgs is None, it registers one generic callback for all messages. """ self.running = True try: self.func = UdpLogger(self.ip_ad, self.port) self.link.add_callback(self.func, self.msgs) except: # noqa import traceback print(traceback.format_exc()) def _stop_fired(self): """Handle the stop udp broadcast button. It uses the self.funcs and self.msgs to remove the callbacks that were registered when the start button was pressed. """ try: self.link.remove_callback(self.func, self.msgs) self.func.__exit__() self.func = None self.running = False except: # noqa import traceback print(traceback.format_exc())
class SbpRelayView(HasTraits): """ Class allows user to specify port, IP address, and message set to relay over UDP. """ running = Bool(False) _network_info = List() configured = Bool(False) broadcasting = Bool(False) msg_enum = Enum('Observations', 'All') ip_ad = String(DEFAULT_UDP_ADDRESS) port = Int(DEFAULT_UDP_PORT) information = String( 'UDP Streaming\n\nBroadcast SBP information received by' ' the console to other machines or processes over UDP. With the \'Observations\'' ' radio button selected, the console will broadcast the necessary information' ' for a rover Piksi to acheive an RTK solution.' '\n\nThis can be used to stream observations to a remote Piksi through' ' aircraft telemetry via ground control software such as MAVProxy or' ' Mission Planner.') start = Button(label='Start', toggle=True, width=32) stop = Button(label='Stop', toggle=True, width=32) network_refresh_button = SVGButton( label='Refresh Network Status', tooltip='Refresh Network Status', filename=resource_filename('console/images/fontawesome/refresh.svg'), width=16, height=16, aligment='center') cell_modem_view = Instance(CellModemView) view = View( VGroup(spring, HGroup( VGroup( Item( 'msg_enum', label="Messages to broadcast", style='custom', enabled_when='not running'), Item( 'ip_ad', label='IP Address', enabled_when='not running'), Item('port', label="Port", enabled_when='not running'), HGroup(spring, UItem( 'start', enabled_when='not running', show_label=False), UItem( 'stop', enabled_when='running', show_label=False), spring)), VGroup( Item( 'information', label="Notes", height=10, editor=MultilineTextEditor( TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ) ), spring, HGroup(Item('cell_modem_view', style='custom', show_label=False), VGroup( Item( '_network_info', style='readonly', editor=TabularEditor( adapter=SimpleNetworkAdapter()), show_label=False, ), Item( 'network_refresh_button', show_label=False, width=0.50), show_border=True, label="Network"), ) ) ) def _network_callback(self, m, **metadata): txstr = sizeof_fmt(m.tx_bytes), rxstr = sizeof_fmt(m.rx_bytes) if m.interface_name.startswith(b'ppp0'): # Hack for ppp tx and rx which doesn't work txstr = "---" rxstr = "---" elif m.interface_name.startswith(b'lo') or m.interface_name.startswith(b'sit0'): return table_row = ((m.interface_name.decode('ascii'), ip_bytes_to_string(m.ipv4_address), ((m.flags & (1 << 6)) != 0), txstr, rxstr)) exists = False for i, each in enumerate(self._network_info): if each[0][0] == table_row[0][0]: self._network_info[i] = table_row exists = True if not exists: self._network_info.append(table_row) def __init__(self, link): """ Traits tab with UI for UDP broadcast of SBP. Parameters ---------- link : sbp.client.handler.Handler Link for SBP transfer to/from Piksi. device_uid : str Piksi Device UUID (defaults to None) whitelist : [int] | None Piksi Device UUID (defaults to None) """ self.link = link # Whitelist used for UDP broadcast view self.cell_modem_view = CellModemView(link) self.msgs = OBS_MSGS # register a callback when the msg_enum trait changes self.on_trait_change(self.update_msgs, 'msg_enum') self.python_console_cmds = {'update': self} self.cellmodem_interface_name = "ppp0" self.link.add_callback(self._network_callback, SBP_MSG_NETWORK_STATE_RESP) def update_msgs(self): """Updates the instance variable msgs which store the msgs that we will send over UDP. """ if self.msg_enum == 'Observations': self.msgs = OBS_MSGS elif self.msg_enum == 'All': self.msgs = [None] else: raise NotImplementedError def _prompt_setting_error(self, text): """Nonblocking prompt for a device setting error. Parameters ---------- text : str Helpful error message for the user """ prompt = CallbackPrompt(title="Setting Error", actions=[close_button]) prompt.text = text prompt.run(block=False) def update_network_state(self): self._network_refresh_button_fired() def _network_refresh_button_fired(self): self._network_info = [] self.link(MsgNetworkStateReq()) def _start_fired(self): """Handle start udp broadcast button. Registers callbacks on self.link for each of the self.msgs If self.msgs is None, it registers one generic callback for all messages. """ self.running = True try: self.func = UdpLogger(self.ip_ad, self.port) self.link.add_callback(self.func, self.msgs) except: # noqa import traceback print(traceback.format_exc()) def _stop_fired(self): """Handle the stop udp broadcast button. It uses the self.funcs and self.msgs to remove the callbacks that were registered when the start button was pressed. """ try: self.link.remove_callback(self.func, self.msgs) self.func.__exit__() self.func = None self.running = False except: # noqa import traceback print(traceback.format_exc())
class SbpRelayView(HasTraits): """ SBP Relay view- Class allows user to specify port, IP address, and message set to relay over UDP and to configure a http connection """ running = Bool(False) configured = Bool(False) broadcasting = Bool(False) msg_enum = Enum('Observations', 'All') ip_ad = String(DEFAULT_UDP_ADDRESS) port = Int(DEFAULT_UDP_PORT) information = String( 'UDP Streaming\n\nBroadcast SBP information received by' ' the console to other machines or processes over UDP. With the \'Observations\'' ' radio button selected, the console will broadcast the necessary information' ' for a rover Piksi to acheive an RTK solution.' '\n\nThis can be used to stream observations to a remote Piksi through' ' aircraft telemetry via ground control software such as MAVProxy or' ' Mission Planner.') show_networking = Bool(False) http_information = String( 'Experimental Piksi Networking\n\n' "Use this widget to connect Piksi receivers to http servers.\n\n") start = Button(label='Start', toggle=True, width=32) stop = Button(label='Stop', toggle=True, width=32) connected_rover = Bool(False) connect_rover = Button(label='Connect', toggle=True, width=32) disconnect_rover = Button(label='Disconnect', toggle=True, width=32) url = String() base_pragma = String() rover_pragma = String() base_device_uid = String() rover_device_uid = String() toggle = True view = View( VGroup(spring, HGroup( VGroup( Item( 'running', show_label=True, style='readonly', visible_when='running'), Item( 'msg_enum', label="Messages to broadcast", style='custom', enabled_when='not running'), Item( 'ip_ad', label='IP Address', enabled_when='not running'), Item('port', label="Port", enabled_when='not running'), HGroup(spring, UItem( 'start', enabled_when='not running', show_label=False), UItem( 'stop', enabled_when='running', show_label=False), spring)), VGroup( Item( 'information', label="Notes", height=10, editor=MultilineTextEditor( TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ), ), spring, HGroup( VGroup( HGroup(spring, UItem( 'connect_rover', enabled_when='not connected_rover', show_label=False), UItem( 'disconnect_rover', enabled_when='connected_rover', show_label=False), spring), HGroup( Spring(springy=False, width=2), Item( 'url', enabled_when='not connected_rover', show_label=True), Spring( springy=False, width=2)), HGroup(spring, Item('base_pragma', label='Base option '), Item('base_device_uid', label='Base device '), spring), HGroup(spring, Item('rover_pragma', label='Rover option'), Item('rover_device_uid', label='Rover device'), spring), ), VGroup( Item( 'http_information', label="Notes", height=10, editor=MultilineTextEditor( TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, ), visible_when='show_networking', ), spring)) def __init__(self, link, show_networking=False, device_uid=None, url='', whitelist=None, rover_pragma='', base_pragma='', rover_uuid='', base_uuid='', connect=False, verbose=False): """ Traits tab with UI for UDP broadcast of SBP. Parameters ---------- link : sbp.client.handler.Handler Link for SBP transfer to/from Piksi. device_uid : str Piksi Device UUID (defaults to None) base : str HTTP endpoint whitelist : [int] | None Piksi Device UUID (defaults to None) """ self.link = link # Whitelist used for UDP broadcast view self.msgs = OBS_MSGS # register a callback when the msg_enum trait changes self.on_trait_change(self.update_msgs, 'msg_enum') # Whitelist used for broadcasting self.whitelist = whitelist self.device_uid = None self.python_console_cmds = {'update': self} self.rover_pragma = rover_pragma self.base_pragma = base_pragma self.rover_device_uid = rover_uuid self.base_device_uid = base_uuid self.verbose = verbose self.http_watchdog_thread = None self.url = url self.show_networking = show_networking if connect: self.connect_when_uuid_received = True else: self.connect_when_uuid_received = False def update_msgs(self): """Updates the instance variable msgs which store the msgs that we will send over UDP. """ if self.msg_enum == 'Observations': self.msgs = OBS_MSGS elif self.msg_enum == 'All': self.msgs = [None] else: raise NotImplementedError def set_route(self, uuid=None, serial_id=None, channel=CHANNEL_UUID): """Sets serial_id hash for HTTP headers. Parameters ---------- uuid: str real uuid of device serial_id : int Piksi device ID channel : str UUID namespace for device UUID """ if uuid: device_uid = uuid elif serial_id: device_uid = str(get_uuid(channel, serial_id % 1000)) else: print( "Improper call of set_route, either a serial number or UUID should be passed" ) device_uid = str(get_uuid(channel, 1234)) print("Setting UUID to default value of {0}".format(device_uid)) self.device_uid = device_uid def _prompt_setting_error(self, text): """Nonblocking prompt for a device setting error. Parameters ---------- text : str Helpful error message for the user """ prompt = CallbackPrompt(title="Setting Error", actions=[close_button]) prompt.text = text prompt.run(block=False) def _disconnect_rover_fired(self): """Handle callback for HTTP rover disconnects. """ try: if isinstance(self.http_watchdog_thread, threading.Thread) and \ not self.http_watchdog_thread.stopped(): self.http_watchdog_thread.stop() else: print(("Unable to disconnect: Http watchdog thread " "inititalized at {0} and connected since {1} has " "already been stopped").format( self.http_watchdog_thread.get_init_time(), self.http_watchdog_thread.get_connect_time())) self.connected_rover = False except: self.connected_rover = False import traceback print(traceback.format_exc()) def _connect_rover_fired(self): """Handle callback for HTTP rover connections. Launches an instance of http_watchdog_thread. """ if not self.device_uid: msg = "\nDevice ID not found!\n\nConnection requires a valid Piksi device ID." self._prompt_setting_error(msg) return try: _base_device_uid = self.base_device_uid or self.device_uid _rover_device_uid = self.rover_device_uid or self.device_uid config = HttpConsoleConnectConfig( self.link, self.device_uid, self.url, self.whitelist, self.rover_pragma, self.base_pragma, _rover_device_uid, _base_device_uid) self.http_watchdog_thread = HttpWatchdogThread( link=self.link, http_config=config, stopped_callback=self._disconnect_rover_fired, verbose=self.verbose) self.connected_rover = True self.http_watchdog_thread.start() except: if isinstance(self.http_watchdog_thread, threading.Thread) \ and self.http_watchdog_thread.stopped(): self.http_watchdog_thread.stop() self.connected_rover = False import traceback print(traceback.format_exc()) def _start_fired(self): """Handle start udp broadcast button. Registers callbacks on self.link for each of the self.msgs If self.msgs is None, it registers one generic callback for all messages. """ self.running = True try: self.func = UdpLogger(self.ip_ad, self.port) self.link.add_callback(self.func, self.msgs) except: import traceback print(traceback.format_exc()) def _stop_fired(self): """Handle the stop udp broadcast button. It uses the self.funcs and self.msgs to remove the callbacks that were registered when the start button was pressed. """ try: self.link.remove_callback(self.func, self.msgs) self.func.__exit__() self.func = None self.running = False except: import traceback print(traceback.format_exc())
class SbpRelayView(HasTraits): """ Class allows user to specify port, IP address, and message set to relay over UDP. """ running = Bool(False) _network_info = List() configured = Bool(False) broadcasting = Bool(False) msg_enum = Enum('Observations', 'All') ip_ad = String(DEFAULT_UDP_ADDRESS) port = Int(DEFAULT_UDP_PORT) information = String( 'UDP Streaming\n\nBroadcast SBP information received by' ' the console to other machines or processes over UDP. With the \'Observations\'' ' radio button selected, the console will broadcast the necessary information' ' for a rover Piksi to acheive an RTK solution.' '\n\nThis can be used to stream observations to a remote Piksi through' ' aircraft telemetry via ground control software such as MAVProxy or' ' Mission Planner.') start = Button(label='Start', toggle=True, width=32) stop = Button(label='Stop', toggle=True, width=32) network_refresh_button = SVGButton( label='Refresh Network Status', tooltip='Refresh Network Status', filename=resource_filename('console/images/fontawesome/refresh.svg'), width=16, height=16, aligment='center') cell_modem_view = Instance(CellModemView) view = View( VGroup( spring, HGroup( VGroup( Item('msg_enum', label="Messages to broadcast", style='custom', enabled_when='not running'), Item('ip_ad', label='IP Address', enabled_when='not running'), Item('port', label="Port", enabled_when='not running'), HGroup( spring, UItem('start', enabled_when='not running', show_label=False), UItem('stop', enabled_when='running', show_label=False), spring)), VGroup( Item('information', label="Notes", height=10, editor=MultilineTextEditor( TextEditor(multi_line=True)), style='readonly', show_label=False, resizable=True, padding=15), spring, )), spring, HGroup( Item('cell_modem_view', style='custom', show_label=False), VGroup(Item( '_network_info', style='readonly', editor=TabularEditor(adapter=SimpleNetworkAdapter()), show_label=False, ), Item('network_refresh_button', show_label=False, width=0.50), show_border=True, label="Network"), ))) def _network_callback(self, m, **metadata): txstr = sizeof_fmt(m.tx_bytes), rxstr = sizeof_fmt(m.rx_bytes) if m.interface_name.startswith( b'ppp0'): # Hack for ppp tx and rx which doesn't work txstr = "---" rxstr = "---" elif m.interface_name.startswith(b'lo') or m.interface_name.startswith( b'sit0'): return table_row = ((m.interface_name.decode('ascii'), ip_bytes_to_string(m.ipv4_address), ((m.flags & (1 << 6)) != 0), txstr, rxstr)) exists = False for i, each in enumerate(self._network_info): if each[0][0] == table_row[0][0]: self._network_info[i] = table_row exists = True if not exists: self._network_info.append(table_row) def __init__(self, link): """ Traits tab with UI for UDP broadcast of SBP. Parameters ---------- link : sbp.client.handler.Handler Link for SBP transfer to/from Piksi. device_uid : str Piksi Device UUID (defaults to None) whitelist : [int] | None Piksi Device UUID (defaults to None) """ self.link = link # Whitelist used for UDP broadcast view self.cell_modem_view = CellModemView(link) self.msgs = OBS_MSGS # register a callback when the msg_enum trait changes self.on_trait_change(self.update_msgs, 'msg_enum') self.python_console_cmds = {'update': self} self.cellmodem_interface_name = "ppp0" self.link.add_callback(self._network_callback, SBP_MSG_NETWORK_STATE_RESP) def update_msgs(self): """Updates the instance variable msgs which store the msgs that we will send over UDP. """ if self.msg_enum == 'Observations': self.msgs = OBS_MSGS elif self.msg_enum == 'All': self.msgs = [None] else: raise NotImplementedError def _prompt_setting_error(self, text): """Nonblocking prompt for a device setting error. Parameters ---------- text : str Helpful error message for the user """ prompt = CallbackPrompt(title="Setting Error", actions=[close_button]) prompt.text = text prompt.run(block=False) def update_network_state(self): self._network_refresh_button_fired() def _network_refresh_button_fired(self): self._network_info = [] self.link(MsgNetworkStateReq()) def _start_fired(self): """Handle start udp broadcast button. Registers callbacks on self.link for each of the self.msgs If self.msgs is None, it registers one generic callback for all messages. """ self.running = True try: self.func = UdpLogger(self.ip_ad, self.port) self.link.add_callback(self.func, self.msgs) except: # noqa import traceback print(traceback.format_exc()) def _stop_fired(self): """Handle the stop udp broadcast button. It uses the self.funcs and self.msgs to remove the callbacks that were registered when the start button was pressed. """ try: self.link.remove_callback(self.func, self.msgs) self.func.__exit__() self.func = None self.running = False except: # noqa import traceback print(traceback.format_exc())