class WorkerReceiver(object): def __init__(self): print "Initializing WorkerReceiver class..." def _init(self): self.context = zmq.Context() self.bind_address = getattr(settings, 'LOGSTREAM_BIND_ADDR', 'ipc:///tmp/logstream_receiver') self.queue = Queue.Queue() def __call__(self): print "Running WorkerReceiver process..." self._init() self.socket = self.context.socket(zmq.PULL) self.socket.bind(self.bind_address) # Starting record processor thread. from threading import Thread self.worker = Thread(target=WorkerProcessor(), args=[self.queue]) self.worker.daemon = True self.worker.start() # Record receiver loop. while True: data = self.socket.recv_pyobj() self.queue.put_nowait(data) def __del__(self): self.worker.terminate() self.socket.close()
class Packenger: def __init__(self): self.receive_queue_length = 0 self.receive_queue = list() self.listen_process = None # for listen on interface in parallel @staticmethod def send(packet, interface): sender = netmap.Netmap() sender.open() sender.if_name = interface sender.register() txr = sender.transmit_rings[0] txr.slots[0].buf[0:len(packet)] = packet txr.slots[0].len = len(packet) txr.cur = txr.head = 1 sender.txsync() sender.close() def __listen(self, interface): receiver = netmap.NetmapDesc('netmap:' + interface) while 1: # sync RX rings with kernel receiver.rxsync() # scan all the receive rings rxr = None for i in range(receiver.interface.rx_rings): if receiver.receive_rings[i].head != receiver.receive_rings[i].tail: # At least one packet has been received on # this ring rxr = receiver.receive_rings[i] break if rxr is None: # no packets received on the rings, let's sleep a bit time.sleep(1) continue # slot pointed by rxr.head has been received # and can be extracted slot = rxr.slots[rxr.head] # convert the buffer associated to the slot to # a string of hexadecimal digits, up to the received length self.receive_queue.append(Packet(slot.buf[:slot.len].tobytes(), slot.buf[:slot.len].tolist(), slot.len)) self.receive_queue_length = self.receive_queue_length + 1 # update head and cur, managing index wraparound rxr.head = rxr.head + 1 if rxr.head >= rxr.num_slots: rxr.head -= rxr.num_slots rxr.cur = rxr.head def start_listen(self, interface): self.listen_process = Thread(target=self.__listen, args=(interface,)) self.listen_process.start() def stop_listen(self): self.listen_process.terminate()
class WorkerReceiver(object): def __init__(self): print "Initializing WorkerReceiver class..." def _init(self): self.context = zmq.Context() self.bind_address = getattr(settings, "LOGSTREAM_BIND_ADDR", "ipc:///tmp/logstream_receiver") self.queue = Queue.Queue() def __call__(self): print "Running WorkerReceiver process..." self._init() self.socket = self.context.socket(zmq.PULL) self.socket.bind(self.bind_address) # Starting record processor thread. from threading import Thread self.worker = Thread(target=WorkerProcessor(), args=[self.queue]) self.worker.daemon = True self.worker.start() # Record receiver loop. while True: data = self.socket.recv_pyobj() self.queue.put_nowait(data) def __del__(self): self.worker.terminate() self.socket.close()
class ThreadedIMU(IMU): def __init__(self, dps=250, gs=2, gyro_bw=100, verbose=False): """ This is a threaded IMU driver. value? add filter to thread? """ IMU.__init__(self, dps=250, gs=2, gyro_bw=100, verbose=False) self.shutting_down = False self.accel = ( 0, 0, 0, ) self.mag = ( 0, 0, 0, ) self.gyro = ( 0, 0, 0, ) self.filter = None def __del__(self): self.stop() def get(self): return ( self.accel, self.mag, self.gyro, ) def run(self, hertz): """Data capture thread""" rate = Rate(hertz) while not self.shutting_down: self.accel, self.mag = self.accel.get() self.gyro = self.gyro.get() rate.sleep() def start(self, hertz): """Start thread""" self.thread = Thread(name='imu_thread', target=self.run, args=(hertz, )) def stop(self, timeout=0.1): """Stop thread""" self.shutting_down = True self.thread.join(timeout) if self.thread.is_alive(): self.thread.terminate()
def bench( server_func, client_func, client_count, server_kwds=None, client_kwds=None, client_max=10, server_join_timeout=1.0 ): """Bench-test the server_func (with optional keyword args from server_kwds) as a process; will fail if one already bound to port. Creates a thread pool (default 10) of client_func. Each client is supplied a unique number argument, and the supplied client_kwds as keywords, and should return 0 on success, !0 on failure. : Both threading.Thread and multiprocessing.Process work fine for running a bench server. However, Thread needs to use the out-of-band means to force server_main termination (since we can't terminate a Thread). This is implemented as a container (eg. dict-based cpppo.apidict) containing a done signal. """ #from multiprocessing import Process from threading import Thread as Process from multiprocessing.pool import ThreadPool as Pool #from multiprocessing.dummy import Pool #from multiprocessing import Pool import time import json log.normal( "Server %r startup...", misc.function_name( server_func )) server = Process( target=server_func, kwargs=server_kwds or {} ) server.daemon = True server.start() time.sleep( .25 ) try: log.normal( "Client %r tests begin, over %d clients (up to %d simultaneously)", misc.function_name( client_func ), client_count, client_max ) pool = Pool( processes=client_max ) # Use list comprehension instead of generator, to force start of all asyncs! asyncs = [ pool.apply_async( client_func, args=(i,), kwds=client_kwds or {} ) for i in range( client_count )] successes = sum( not a.get() for a in asyncs ) failures = client_count - successes log.normal( "Client %r tests done: %d/%d succeeded (%d failures)", misc.function_name( client_func ), successes, client_count, failures ) return failures finally: # Shut down server; use 'server.control.done = true' to stop server, if # available in server_kwds. If this doesn't work, we can try terminate control = server_kwds.get( 'server', {} ).get( 'control', {} ) if server_kwds else {} if 'done' in control: log.normal( "Server %r done signalled", misc.function_name( server_func )) control['done'] = True # only useful for threading.Thread; Process cannot see this if hasattr( server, 'terminate' ): log.normal( "Server %r done via .terminate()", misc.function_name( server_func )) server.terminate() # only if using multiprocessing.Process(); Thread doesn't have server.join( timeout=server_join_timeout ) if server.is_alive(): log.warning( "Server %r remains running...", misc.function_name( server_func )) else: log.normal( "Server %r stopped.", misc.function_name( server_func ))
class Orderbook(object): def __init__(self, uuid): self.uuid = uuid # + uuid4().hex self.keymanager = RedisKeyManager(uuid) self.buy_orders = list() self.sell_orders = list() self.redis = Redis() logger.info('Initializing orderbook: %s'%self.uuid) def start_auction(self): """ Run this to start the auction. If the auction is already running, nothing happens""" if not hasattr(self, 'daemon'): self.daemon = Thread(name = 'auction_%s'%self.uuid, target = self.queue_daemon) self.daemon.start() # self.osn = Thread(name = 'orderbookstatus_%s'%self.uuid, target = self.orderbook_status_notifier) # self.osn.start() # Auction.query.filter_by(uuid = self.uuid).update({'running' : True}) logger.info('Started auction for book %s'%self.uuid) else: logger.info('Auction is already running at book %s'%self.uuid) def stop_auction(self): if hasattr(self, 'daemon'): self.daemon.terminate() # Auction.query.filter_by(uuid = self.uuid).update({'running' : False}) del self.daemon logger.info('Terminated auction at book %s'%self.uuid) else: logger.info('Cannot stop auction that is not already running at book %s'%self.uuid) def queue_daemon(self, rv_ttl=500): """ The daemon that listens for incoming orders. Must be run in a separate process. All received orders are stored in the database """ while True: logger.debug('Waiting for orders...') order_form_data = self.redis.blpop(prefixed(self.uuid)) order_form_data = loads(order_form_data[1]) new_order = Order(**order_form_data) self.store_order(new_order) try: response = self.process_order(new_order) logger.debug('Finished processing order.') except Exception, e: logger.exception(e) response = e
class Audio_Capture(object): """ PyAV based audio capture. """ def __init__(self, file_loc,audio_src=0): super(Audio_Capture, self).__init__() try: file_path,ext = file_loc.rsplit('.', 1) except: logger.error("'%s' is not a valid media file name."%file_loc) raise Exception("Error") if ext not in ('wav'): logger.error("media file container should be wav. Using a different container is not supported.") raise NotImplementedError() self.should_close = Event() self.process = None self.start(file_loc,audio_src) def start(self,file_loc, audio_src): # from rec_thread import rec_thread try: from billiard import forking_enable forking_enable(0) except ImportError: pass self.should_close.clear() self.process = Process(target=rec_thread, args=(file_loc, audio_src,self.should_close)) self.process.start() try: forking_enable(1) except: pass def stop(self): self.should_close.set() self.process.join(timeout=1) try: self.process.terminate() except: logger.error('Could not joind recording thread.') self.process = None def close(self): self.stop() def __del__(self): if self.process: self.stop()
class Audio_Capture(object): """ PyAV based audio capture. """ def __init__(self, file_loc, audio_src=0): super(Audio_Capture, self).__init__() try: file_path, ext = file_loc.rsplit('.', 1) except: logger.error("'%s' is not a valid media file name." % file_loc) raise Exception("Error") if ext not in ('wav'): logger.error( "media file container should be wav. Using a different container is not supported." ) raise NotImplementedError() self.should_close = Event() self.process = None self.start(file_loc, audio_src) def start(self, file_loc, audio_src): # from rec_thread import rec_thread try: from billiard import forking_enable forking_enable(0) except ImportError: pass self.should_close.clear() self.process = Process(target=rec_thread, args=(file_loc, audio_src, self.should_close)) self.process.start() try: forking_enable(1) except: pass def stop(self): self.should_close.set() self.process.join(timeout=1) self.process.terminate() self.process = None def close(self): self.stop() def __del__(self): if self.process: self.stop()
def OnKeyboardEvent(event): print(event.Key) if ("Space" == event.Key): print("enter Space!") #True开始运行新线程 task = threadPlayTask() t = Thread(target=task.run, args=[ 15, ]) t.start() #反之,开始终止线程运行 if ("F7" == event.Key): print("Thread killed!") t.terminate()
class _RunInBackground(object): def __init__(self, app, is_alive_route, host=None, port=None): self.app = app self.host = host self.port = port self.should_suicide = False self.is_alive_route = is_alive_route if isWindows: Thread(target=self.middleware_thread).start() else: self.process = Process(target=self.app._run, args=(self.host, self.port)) self.process.start() def middleware_thread(self): self.process = Thread(target=self.app._run, args=(self.host, self.port)) self.process.daemon = True self.process.start() while True: if self.should_suicide: break time.sleep(0.1) def __enter__(self): is_alive = False for _ in range(40): try: r = requests.put("http://" + self.host + ":" + str(self.port) + self.is_alive_route) if r.status_code == 200: is_alive = True break except: pass time.sleep(0.05) if not is_alive: raise Exception("Server isn't alive") def __exit__(self, a, b, c): if not isWindows: self.process.terminate() self.should_suicide = True
def run(self): try: # init replica thread t_replica = Thread(target = self.replicaThread, args=()) t_replica.start() while(1): conn, addr = self.socket.accept() # accept print('Connected by', addr) # addr = (host, port) # init a server thread for a client t_serverThread = Thread(target = self.serverThread, args=(conn, )) t_serverThread.start() except: print("CTRL C occured") finally: print("exit server thread") self.socket.close() t_replica.terminate()
def run(self): try: # init replica thread t_replica = Thread(target=self.replicaThread, args=()) t_replica.start() while (1): conn, addr = self.socket.accept() # accept print('Connected by', addr) # addr = (host, port) # init a server thread for a client t_serverThread = Thread(target=self.serverThread, args=(conn, )) t_serverThread.start() except: print("CTRL C occured") finally: print("exit server thread") self.socket.close() t_replica.terminate()
class Comms: def __init__(self, *, queue: Queue): self.queue = queue # Implement this function to add received commands to the queue forever def read_telemetry_forever(self): raise NotImplementedError # Receive commands and add them to the queue indefinitely def listen(self): self.listening_thread = Thread(target=self.read_telemetry_forever) self.listening_thread.start() # Override this method to assure safety for specific implementation def stop(self): print("Halting comms thread...") if self.listening_thread.is_alive() is True: self.listening_thread.terminate() def send_packet(self, packet: bytes): raise NotImplementedError
def handle_websocket(device='all', mode='transfer_rate'): if (device == 'all'): device_list = [] else: device_list = device.split('_') if debugMode: pprint(device_list) pprint(mode) print '******************************************' tommy = NethogsWatchdog(devices=device_list) bridge = {'queue': Queue(), 'event': Event()} t = Thread(target=tommy.watch_transfer, args=(mode, bridge)) t.daemon = True try: t.start() wsock = request.environ.get('wsgi.websocket') if not wsock: tommy.terminate() bridge['event'].set() abort(400, 'Expected WebSocket request.') while True: try: message = wsock.receive() report = bridge['queue'].get() wsock.send(json.dumps(report)) gevent.sleep(0.1) except WebSocketError: tommy.terminate() bridge['event'].set() break except (KeyboardInterrupt, SystemExit): t.terminate() sys.exit()
def preview(self, port=3131): processWatcher = Thread(target=self.regenerate) processWatcher.start() self.generate() from http.server import HTTPServer, SimpleHTTPRequestHandler HandlerClass = SimpleHTTPRequestHandler HandlerClass.protocol_version = "HTTP/1.1" ServerClass = HTTPServer server_address = ('', port) httpd = ServerClass(server_address, HandlerClass) sa = httpd.socket.getsockname() os.chdir(self.sitepath) print("Serving HTTP on", sa[0], "port", sa[1], "...") try: httpd.serve_forever() except KeyboardInterrupt: print("\nKeyboard interrupt received, exiting.") processWatcher.terminate() httpd.server_close() sys.exit(0)
def tcp_serv(): #register publisher pub = rospy.Publisher("dji_img_file", String, queue_size=10) rospy.init_node('tcpReceiver', anonymous=True) #open TCP-socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.bind((TCP_IP, TCP_PORT)) except socket.error as msg: s.close print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1] rospy.signal_shutdown("Port already in Use") return #listen for connection s.listen(1) print 'Listening on {}:{}'.format(TCP_IP, TCP_PORT) #wait to accept a connection - blocking call conn, addr = s.accept() print 'Connected with ' + addr[0] + ':' + str(addr[1]) CONNECTED = True #connection established, start receiving Thread (as defines above) t = Thread(target=clientthread, args=(conn, pub)) t.daemon = True t.start() try: while CONNECTED: time.sleep(0.1) except (KeyboardInterrupt, SystemExit): t.terminate() print "Closed TCP-Connection!" s.close()
class Player(): def __init__(self): self.playlist = [] self.internal_play_flag = False self.player_state = "Stopped" self.player_thread = None # self.player_thread = Thread(target=self.build_player) # self.player_thread.start() """ Allow dbus to be refreshed """ sleep(1) """ Allow dbus to be refreshed """ # self.bus = dbus.SessionBus() self.proxy = None self.player = None self.properties_manager = None # self.properties_manager.Set('org.mpris.MediaPlayer2.Player', 'Volume', .7) # Set initial volume self.watcher_thread = None # self.watcher_thread = Thread(target=self.build_watcher) # self.watcher_thread.start() def build_player(self): Popen(['cvlc', '--control', 'dbus']) self.bus = dbus.SessionBus() self.proxy = self.bus.get_object('org.mpris.MediaPlayer2.vlc','/org/mpris/MediaPlayer2') self.player = dbus.Interface(self.proxy, 'org.mpris.MediaPlayer2.Player') self.properties_manager = dbus.Interface(self.proxy, 'org.freedesktop.DBus.Properties') self.properties_manager.Set('org.mpris.MediaPlayer2.Player', 'Volume', .7) # Set initial volume def build_watcher(self): while True: try: """ Are we playing back or stopped? """ if (self.internal_play_flag == True): """ If playback is just stopped and there is more in the queue it's time to move the queue """ if ((self.get_playback_status() == "Stopped") & (len(self.playlist) > 0)): try: print "##### Playing next track. #####" """ Remove the last played item """ self.playlist.pop(0) """ Open the next Uri""" self.open_uri(self.playlist[0].url) urlopen('http://localhost:5000/new_track') except: print "##### The queue is empty. #####" self.player_state = "Stopped" self.player_thread.terminate() self.watcher_thread.terminate() urlopen('http://localhost:5000/new_track') urlopen('http://localhost:5000/player_state') """ There is nothing to play - I think vlc will naturally handle it.""" # print "##### Playing and playlist greater than 0 #####" sleep(1) except: print self.get_playback_status() sleep(1) """ Add a stream from youtube """ def add_stream_from_youtube(self, youtube_url): # returns stream object if (youtube_url.startswith('http')): url = youtube_url else: url = 'https://www.youtube.com/watch?v=' + str(youtube_url) try: video = pafy.new(url) audiostreams = video.audiostreams best = video.getbestaudio() s = Stream(best.title, best.url) self.playlist.append(s) if (len(self.playlist) == 1): self.player_thread = Thread(target=self.build_player()) self.watcher_thread = Thread(target=self.build_watcher()) self.player_thread.start() self.watcher_thread.start() self.play_or_pause() self.player_state = "Playing" urlopen('http://localhost:5000/new_track') urlopen('http://localhost:5000/player_state') except: print "had a problem adding" """ Stop player process """ def kill_player(self): self.internal_play_flag = False self.player_thread.terminate() self.watcher_thread.terminate() """ Play next in queue """ def play_next(self): if ((self.internal_play_flag == False) & len(self.playlist) > 1): # Begin playing if we are stopped and hit next self.internal_play_flag = True try: print "##### Buffering the next track #####" # Try to play the next track self.player_state = "Buffering" # Set our state to buffering urlopen('http://localhost:5000/player_state')# Update state self.playlist.pop(0) # Pop the current element self.open_uri(self.playlist[0].url) # Open the next stream self.player_state = "Playing" urlopen('http://localhost:5000/player_state') except: # Somethings wrong with the stream and there is something else self.playlist.pop(0) self.play_next() """ Returns the current volume """ def get_current_volume(self): return self.properties_manager.Get('org.mpris.MediaPlayer2.Player', 'Volume') """ Pass in an int to set the volume """ def set_volume(self, volume): if (volume >= 0 & volume <= 1.0): self.properties_manager.Set('org.mpris.MediaPlayer2.Player', 'Volume', volume) else: print "Volume out of range - Please use 0.0 - 1.0" """ Decrease the volume by 10 percent """ def decrease_volume(self): self.properties_manager.Set('org.mpris.MediaPlayer2.Player', 'Volume', (self.get_current_volume()-.10)) """ Increase the volume by 10 percent """ def increase_volume(self): self.properties_manager.Set('org.mpris.MediaPlayer2.Player', 'Volume', (self.get_current_volume()+.10)) """ Play if paused or stopped else pause """ def play_or_pause(self): if (len(self.playlist) == 0): print "##### No tracks to play #####" return if (self.internal_play_flag == False): """ If we are starting the queue for the first time set our internal play flag and begin the first queue item """ self.internal_play_flag = True self.open_uri(self.playlist[0].url) self.player_state = "Playing" urlopen('http://localhost:5000/player_state') else: self.player.PlayPause() if (self.get_playback_status() == "Paused"): self.player_state = "Paused" urlopen('http://localhost:5000/player_state') else: self.player_state = "Playing" urlopen('http://localhost:5000/player_state') """ Returns true if the player is playing """ def get_playback_status(self): return self.properties_manager.Get('org.mpris.MediaPlayer2.Player', 'PlaybackStatus') """ Returns the playback status as True or False """ def get_playback_status_true_false(self): try: if (self.get_playback_status() == "Playing"): return True else: return False except: print "##### Thread not active #####" """ Converts the in memory object to an array of dictionaries and then loads that into json """ def get_playlist(self): res = json.dumps(self.playlist, default=lambda o: o.__dict__) # so like, black magic and shit j = json.loads(res) return j """ Open remote streams """ def open_uri(self, uri): self.player.OpenUri(uri)
class Manager(object): """Manager This is the base Manager of the BaseComponent which manages an Event Queue, a set of Event Handlers, Channels, Tick Functions, Registered and Hidden Components, a Task and the Running State. :ivar manager: The Manager of this Component or Manager """ def __init__(self, *args, **kwargs): "initializes x; see x.__class__.__doc__ for signature" self._globals = [] self._cmap = dict() self._tmap = dict() self._queue = deque() self.channels = dict() self._handlers = set() self._handlerattrs = dict() self._ticks = set() self._task = None self._running = False self.root = self.manager = self self.components = set() def __repr__(self): "x.__repr__() <==> repr(x)" name = self.__class__.__name__ if hasattr(self, "channel") and self.channel is not None: channel = "/%s" % self.channel else: channel = "" q = len(self._queue) c = len(self.channels) h = len(self._handlers) state = self.state if HAS_MULTIPROCESSING == 2: pid = current_process().ident if HAS_MULTIPROCESSING == 1: pid = current_process().getPid() else: pid = os.getpid() if pid: id = "%s:%s" % (pid, current_thread().getName()) else: id = current_thread().getName() format = "<%s%s %s (queued=%d, channels=%d, handlers=%d) [%s]>" return format % (name, channel, id, q, c, h, state) def __contains__(self, y): """x.__contains__(y) <==> y in x Return True if the Component y is registered. """ components = self.components.copy() return y in components or y in [c.__class__ for c in components] def __len__(self): """x.__len__() <==> len(x) Returns the number of events in the Event Queue. """ return len(self._queue) def __add__(self, y): """x.__add__(y) <==> x+y (Optional) Convenience operator to register y with x Equivalent to: y.register(x) @return: x @rtype Component or Manager """ y.register(self) return self def __iadd__(self, y): """x.__iadd__(y) <==> x += y (Optional) Convenience operator to register y with x Equivalent to: y.register(x) @return: x @rtype Component or Manager """ y.register(self) return self def __sub__(self, y): """x.__sub__(y) <==> x-y (Optional) Convenience operator to unregister y from x.manager Equivalent to: y.unregister() @return: x @rtype Component or Manager """ if y.manager is not y: y.unregister() return self def __isub__(self, y): """x.__sub__(y) <==> x -= y (Optional) Convenience operator to unregister y from x Equivalent to: y.unregister() @return: x @rtype Component or Manager """ if y.manager is not y: y.unregister() return self def _getHandlers(self, _channel): target, channel = _channel channels = self.channels exists = self.channels.has_key get = self.channels.get tmap = self._tmap.get cmap = self._cmap.get def _sortkey(handler): return (self._handlerattrs[handler]["priority"], self._handlerattrs[handler]["filter"]) # Global Channels handlers = self._globals[:] # This channel on all targets if channel == "*": handlers.extend(tmap(target, [])) handlers.sort(key=_sortkey, reverse=True) return handlers # Every channel on this target if target == "*": handlers.extend(cmap(channel, [])) handlers.sort(key=_sortkey, reverse=True) return handlers # Any global channels if exists(("*", channel)): handlers.extend(get(("*", channel))) # Any global channels for this target if exists((channel, "*")): handlers.extend(get((channel, "*"))) # The actual channel and target if exists(_channel): handlers.extend(get((_channel))) handlers.sort(key=_sortkey, reverse=True) return handlers @property def name(self): """Return the name of this Component/Manager""" return self.__class__.__name__ @property def running(self): """Return the running state of this Component/Manager""" return self._running @property def state(self): """Return the current state of this Component/Manager The state can be one of: - [R]unning - [D]ead - [S]topped """ if self.running or (self._task and self._task.isAlive()): return "R" elif self._task and not self._task.isAlive(): return "D" else: return "S" def addHandler(self, handler, *channels, **kwargs): """Add a new Event Handler Add a new Event Handler to the Event Manager. """ channels = getattr(handler, "channels", channels) target = kwargs.get("target", getattr(handler, "target", getattr(self, "channel", "*"))) if isinstance(target, Manager): target = getattr(target, "channel", "*") attrs = {} attrs["channels"] = channels attrs["target"] = target attrs["filter"] = getattr(handler, "filter", kwargs.get("filter", False)) attrs["priority"] = getattr(handler, "priority", kwargs.get("priority", 0)) if not hasattr(handler, "event"): args = getargspec(handler)[0] if args and args[0] == "self": del args[0] attrs["event"] = bool(args and args[0] == "event") else: attrs["event"] = getattr(handler, "event") self._handlerattrs[handler] = attrs def _sortkey(handler): return (self._handlerattrs[handler]["priority"], self._handlerattrs[handler]["filter"]) if not channels and target == "*": if handler not in self._globals: self._globals.append(handler) self._globals.sort(key=_sortkey, reverse=True) else: for channel in channels: self._handlers.add(handler) if (target, channel) not in self.channels: self.channels[(target, channel)] = [] if handler not in self.channels[(target, channel)]: self.channels[(target, channel)].append(handler) self.channels[(target, channel)].sort(key=_sortkey, reverse=True) if target not in self._tmap: self._tmap[target] = [] if handler not in self._tmap[target]: self._tmap[target].append(handler) if channel not in self._cmap: self._cmap[channel] = [] if handler not in self._cmap[channel]: self._cmap[channel].append(handler) add = addHandler def removeHandler(self, handler, channel=None): """Remove an Event Handler Remove the given Event Handler from the Event Manager removing it from the given channel. if channel is None, remove it from all channels. This will succeed even if the specified handler has already been removed. """ if channel is None: if handler in self._globals: self._globals.remove(handler) channels = self.channels.keys() else: channels = [channel] if handler in self._handlers: self._handlers.remove(handler) if handler in self._handlerattrs: del self._handlerattrs[handler] for channel in channels: if handler in self.channels[channel]: self.channels[channel].remove(handler) if not self.channels[channel]: del self.channels[channel] (target, channel) = channel if target in self._tmap and handler in self._tmap: self._tmap[target].remove(handler) if not self._tmap[target]: del self._tmap[target] if channel in self._cmap and handler in self._cmap: self._cmap[channel].remove(handler) if not self._cmap[channel]: del self._cmap[channel] remove = removeHandler def _fire(self, event, channel): self._queue.append((event, channel)) def fireEvent(self, event, channel=None, target=None): """Fire/Push a new Event into the system (queue) This will push the given Event, Channel and Target onto the Event Queue for later processing. if target is None, then target will be set as the Channel of the current Component, self.channel (defaulting back to None). If this Component's Manager is itself, enqueue on this Component's Event Queue, otherwise enqueue on this Component's Manager. :param event: The Event Object :type event: Event :param channel: The Channel this Event is bound for :type channel: str @keyword target: The target Component's channel this Event is bound for :type target: str or Component """ if channel is None and target is None: if type(event.channel) is TupleType: target, channel = event.channel else: channel = event.channel or event.name.lower() target = event.target or None else: channel = channel or event.channel or event.name.lower() if isinstance(target, Manager): target = getattr(target, "channel", "*") else: target = target or event.target or getattr(self, "channel", "*") event.channel = (target, channel) event.value = Value(event, self) if event.start is not None: self.fire(Start(event), *event.start) self.root._fire(event, (target, channel)) return event.value fire = push = fireEvent def _flush(self): q = self._queue self._queue = deque() while q: self.__handleEvent(*q.popleft()) def flushEvents(self): """Flush all Events in the Event Queue This will flush all Events in the Event Queue. If this Component's Manager is itself, flush all Events from this Component's Event Queue, otherwise, flush all Events from this Component's Manager's Event Queue. """ self.root._flush() flush = flushEvents def __handleEvent(self, event, channel): eargs = event.args ekwargs = event.kwargs retval = None handler = None for handler in self._getHandlers(channel): attrs = self._handlerattrs[handler] event.handler = handler try: if attrs["event"]: retval = handler(event, *eargs, **ekwargs) else: retval = handler(*eargs, **ekwargs) event.value.value = retval except (KeyboardInterrupt, SystemExit): raise except: etype, evalue, etraceback = _exc_info() event.value.errors = True event.value.value = etype, evalue, format_tb(etraceback) self.fire(Error(etype, evalue, format_tb(etraceback), handler)) if event.failure is not None: error = (etype, evalue, format_tb(etraceback)) self.fire(Failure(event, handler, error), *event.failure) if retval is not None: if retval and attrs["filter"]: if event.filter is not None: self.fire(Filter(event, handler, retval), *event.filter) return # Filter if event.success is not None: self.fire(Success(event, handler, retval), *event.success) if event.end is not None: self.fire(End(event, handler, retval), *event.end) def _signalHandler(self, signal, stack): self.fire(Signal(signal, stack)) if signal in [SIGINT, SIGTERM]: self.stop() def start(self, sleep=0, log=True, link=None, process=False): group = None target = self.run name = self.__class__.__name__ mode = "P" if process else "T" args = (sleep, log, mode) if process and HAS_MULTIPROCESSING: if link is not None and isinstance(link, Manager): from circuits.net.sockets import Pipe from circuits.core.bridge import Bridge from circuits.core.utils import findroot root = findroot(link) parent, child = Pipe() self._bridge = Bridge(root, socket=parent) self._bridge.start() args += (child,) self._task = Process(group, target, name, args) self._task.daemon = True if HAS_MULTIPROCESSING == 2: setattr(self._task, "isAlive", self._task.is_alive) self.tick() self._task.start() return self._task = Thread(group, target, name, args) self._task.setDaemon(True) self._task.start() def stop(self): self._running = False self.fire(Stopped(self)) if self._task and type(self._task) is Process and self._task.isAlive(): if not current_process() == self._task: self._task.terminate() self._task = None self.tick() def tick(self): if self._ticks: try: [f() for f in self._ticks.copy()] except: etype, evalue, etraceback = _exc_info() self.fire(Error(etype, evalue, format_tb(etraceback))) if self: self._flush() def run(self, sleep=0, log=True, __mode=None, __socket=None): if not __mode == "T" and current_thread().getName() == "MainThread": if os.name == "posix": _registerSignalHandler(SIGHUP, self._signalHandler) _registerSignalHandler(SIGINT, self._signalHandler) _registerSignalHandler(SIGTERM, self._signalHandler) if __socket is not None: from circuits.core.bridge import Bridge manager = Manager() bridge = Bridge(manager, socket=__socket) self.register(manager) manager.start() self._running = True self.fire(Started(self, __mode)) try: while self or self.running: self.tick() if sleep: time.sleep(sleep) finally: if __socket is not None: while bridge or manager: pass manager.stop() bridge.stop()
thread.start() thread2 = Thread(target=create_spectrograms, args=(self.buffer, self.buffer_images)) thread2.start() thread3 = Thread(target=show_images, args=( self.rtp, self.buffer_images)) thread3.start() print("showing...") try: self.rtp.show() app.exec_() print("joining...") thread3.join() except Exception as e: app.exit() if __name__ == '__main__': try: thread2 = Thread(target=record) thread2.daemon = True thread2.start() thread2.join() except Exception as e: thread2.terminate() # app = QtGui.QApplication([]) # recorder = Recorder() # recorder.start()
def run(self, cluster=None, verbose=False): """ Runs all the tasks in a smart order with many at once. Will not return until all tasks are done. Giving a cluster (as a Cluster object) means that the cluster is used for any tasks that are added with can_run_on_cluster=True. Setting verbose to True will cause the time and the command to print whenever a new command is about to start. """ # Checks if self.__conditional != None: raise ValueError('Tasks already running') if len(self.inputs) == 0 and len(self.generators) == 0 and len( self.outputs) == 0 and len(self.cleanups) == 0: return if (len(self.inputs) == 0 and len(self.generators) == 0) or (len( self.outputs) == 0 and len(self.cleanups) == 0): raise ValueError('Invalid set of tasks (likely cyclic)') prev_signal = None try: # Create basic variables and lock self._cluster = cluster self.__error = False self.__killing = False self.__conditional = Condition( ) # for locking access to Task.done, cpu_pressure, mem_pressure, next, last, log, and error self.__running = set() # Setup log done_tasks = self.__process_log() if exists(self.logname) else () self.__log = open(self.logname, 'w', 0) for k, v in self.settings.iteritems(): self.__log.write("*" + k + "=" + str(v) + "\n") # TODO: log overall inputs and outputs for dc in done_tasks: if verbose: print "Skipping " + dc[20:].strip() self.__log.write(dc + "\n") if verbose and len(done_tasks) > 0: print '-' * 80 self._rusagelog = open(self.rusage_log, 'a', 1) if self.rusage_log else None # Calcualte the set of first and last tasks self.__calc_next() # These are the first tasks last = {self.outputs[f] for f in self.overall_outputs()} last |= self.cleanups if len(last) == 0: raise ValueError('Tasks are cyclic') self.__last = {t for t in last if not t.done} # Get the initial pressures self.__cpu_pressure = 0 self.__mem_pressure = get_mem_used_by_tree( ) + 1 * MB # assume that the creation of threads and everything will add some extra pressure # Set a signal handler try: from signal import signal, SIGUSR1 prev_signal = signal(SIGUSR1, self.display_stats) except: pass # Keep running tasks in the tree until we have completed the root (which is self) with self.__conditional: while len(self.__last) != 0: # Get next task (or wait until all tasks or finished or an error is generated) while len(self.__last) > 0 and not self.__error: task = self.__next_task() if task != None: break self.__conditional.wait( 30 ) # wait until we have some available [without the timeout CTRL+C does not work and we cannot see if memory is freed up on the system] if len(self.__last) == 0 or self.__error: break # Run it self.__running.add(task) t = Thread(target=self.__run, args=(task, )) t.daemon = True if verbose: print strftime( Tasks.__time_format) + " Running " + str(task) t.start() sleep(0) # make sure it starts # There was an error, let running tasks finish if self.__error and len(self.__running) > 0: write_error( "Waiting for other tasks to finish running.\nYou can terminate them by doing a CTRL+C." ) while len(self.__running) > 0: self.__conditional.wait( 60 ) # wait until a task stops [without the timeout CTRL+C does not work] except KeyboardInterrupt: # Terminate and kill tasks write_error("Terminating running tasks") with self.__conditional: self.__killing = True for t in self.__running: try: t.terminate() except: pass secs = 0 while len(self.__running) > 0 and secs < 10: self.__conditional.wait(1) secs += 1 for t in self.__running: try: p.kill() except: pass finally: # Cleanup if prev_signal: signal(SIGUSR1, prev_signal) if hasattr(self, '__log'): self.__log.close() del self.__log if hasattr(self, '_rusagelog'): if self._rusagelog: self._rusagelog.close() del self._rusagelog if hasattr(self, '__cpu_pressure'): del self.__cpu_pressure if hasattr(self, '__mem_pressure'): del self.__mem_pressure if hasattr(self, '__running'): del self.__running if hasattr(self, '__next'): del self.__next self.__conditional = None del self._cluster del self.__error del self.__killing
elif started and otherUser: lprint('other users loged in. killing the process...') kill(pid) lprint('killed') started = False elif not started and not otherUser: lprint('starting the process...') pid = os.fock() if pid == 0: Popen(['ssh', '-t', hostname, cmd]) sys.exit(0) else: started = True time.sleep(1) cmd = raw_input('input command:') ps = [] for i in range(2,5): hostname = 'galaxy{:03d}'.format(i) p = Thread(target = worker, args = (hostname, cmd)) ps.append(p) p.start() raw_input('press enter to terminate...') for p in ps: p.terminate()
class MainWindow(object): def __init__(self): self.video_process = None self.update_process = None self.imgQueue = Queue() self.root = tk.Tk() self.root.resizable(width=False, height=False) # Define the fm1 to contain the label which show the video self.fm1 = ttk.Frame(self.root) self.showLabel = tk.Label(self.fm1) # Define the fm2 to contain the three botton self.fm2 = ttk.Frame(self.root) self.bt_start = ttk.Button(self.fm2, text='开始', command=self.startButtonAction) self.bt_stop = ttk.Button(self.fm2, text='停止', command=self.stopButtonAction) self.bt_config = ttk.Button(self.fm2, text='配置') self._arrangeMainWindow() def _arrangeMainWindow(self): ''' image = Image.open('./lena.jpg') image = image.resize((400, 300), Image.ANTIALIAS) self.render = ImageTk.PhotoImage(image) self.showLabel['image'] = self.render ''' self.showLabel['text'] = str(42) self.showLabel.pack(side='top', padx=10, pady=10) self.fm1.pack(side='top') # Define the fm2 to contain the three botton self.bt_start.pack(side='left') self.bt_stop.pack(side='left') self.bt_config.pack(side='left') self.fm2.pack(side='top', pady=10) def _updateThread(self): while True: sentValue = self.imgQueue.get() print('Get value from the queue: ', sentValue) self.showLabel['text'] = str(sentValue) time.sleep(0.5) def _startUpdateThread(self): if self.update_process == None: self.update_process = Thread(target=self._updateThread) if not self.update_process.is_alive(): self.update_process.start() def _videoProcess(self): while True: sendValue = random() self.imgQueue.put(sendValue) print('Sent value: ', sendValue) sleep(0.5) def _startVideoProcess(self): if self.video_process == None: self.video_process = Process(target=self._videoProcess) if not self.video_process.is_alive(): self.video_process.start() def startButtonAction(self): self._startUpdateThread() print('update process started. ') self._startVideoProcess() print('video process started. ') def stopButtonAction(self): if self.video_process.is_alive(): self.video_process.terminate() self.video_process.join() if self.update_process.is_alive(): self.update_process.terminate() self.update_process.join()
class ServiceThread(Thread): def __init__(self, service, logfile): super().__init__() self.__service = service self.__logfile = logfile self.__request_queue = Queue() self.__dependencies = [] self.__children = [] self.__handlers = { ServiceThreadMessage.START : self.__start, ServiceThreadMessage.STOP : self.__stop, ServiceThreadMessage.RESTART : self.__restart, ServiceThreadMessage.HALT : self.__halt, ServiceThreadMessage.ADD_CHILD : self.__add_child, ServiceThreadMessage.ADD_DEPENDENCY : self.__add_dependency, } self.__process_thread = Thread() self.__terminated = Event() # TODO: replace with state? self.__running = False def service(self): return self.__service def logfile(self): return self.__logfile def run(self): logging.info("{} >> Ready".format(self)) while not self.__terminated.is_set(): _message = self.__request_queue.get() self.__handlers.get(_message[0])(_message[1:]) self.__request_queue.task_done() def put_request(self, message, block=False): self.__request_queue.put(message) if block: self.__request_queue.join() def is_running(self): return self.__running == True; def __start(self, message): logging.info("{} << Received START message".format(self)) if not self.__dependencies_running(): logging.info("{} << Unable to perform START: missing dependencies".format(self)) return self.__process_thread = ProcessThreadFactory.create(self, self.__logfile) self.__process_thread.start() logging.info("{} >> Response from [{}]: {}".format( self, self.__process_thread, self.__process_thread.get_response() )) self.__running = True self.__notify((ServiceThreadMessage.RESTART,)) def __dependencies_running(self): for dependency in self.__dependencies: if not dependency.is_running(): logging.info("{} << [{}] is not yet started".format(self, dependency)) return False return True def __stop(self, message): logging.info("{} << Received STOP message".format(self)) if self.__process_thread.is_alive(): self.__process_thread.terminate() logging.info("{} >> Response from [{}]: {}".format( self, self.__process_thread, self.__process_thread.get_response() )) self.__running = False def __restart(self, message): # TODO: Max restart-retry-count # we have to calculate the number of restart per unit time # we have to store the last valid restart-time logging.info("{} << Received RESTART message".format(self)) self.__stop(message) self.__start(message) def __halt(self, message): logging.info("{} << Received HALT message".format(self)) self.__stop(message) self.__terminated.set() def __add_child(self, message): _child = message[0] self.__children.append(_child) logging.info("{} >> Registered to publish over [{}]".format(self, _child)) def __add_dependency(self, message): _dependency = message[0] self.__dependencies.append(_dependency) logging.info("{} >> Registered dependency [{}]".format(self, _dependency)) def __notify(self, message): for child in self.__children: child.put_request(message) def __str__(self): return "{}:{}".format(self.__class__.__name__, self.__service)
if __name__ == '__main__': for i in range(10): print("Parent: iteration %d" % i) print("Parent: Creating child Thread.") q = Queue() t0 = time() t = Thread(target=child, args=(q, t0)) t.daemon = True # print("Parent: Starting child thread.") t.start() # print("Parent: waiting some seconds.") sleep(1) if not q.empty(): t_child = q.get() print("Parent: got this from child thread %ssec." % t_child) else: print("Parent: nothing arrived from child thread.") if t.is_alive(): print("Parent: terminating child thread.") t.terminate() print("Parent: child thread terminated.") print("") print("")
for i in range(readings): vals.append(i) # Load default font. font = ImageFont.load_default() #initiate ADC adc = MCP3008() #Create Class Sensor = readSensors() #Create Thread SensorThread = Thread(target=Sensor.run) #Start Thread SensorThread.start() while True: try: x = (sensval / 1023.0) * (width - 1) # Draw a black filled box to clear the image. draw.rectangle((0, 0, width, height), outline=0, fill=0) draw.rectangle((0, 20, x * 2, height / 8 - 1), outline=0, fill=1) # Display image. disp.image(image) disp.display() #time.sleep(.1) except KeyboardInterrupt as e: sys.exit(e) SensorThread.terminate()
def run(self, cluster=None, verbose=False): """ Runs all the tasks in a smart order with many at once. Will not return until all tasks are done. Giving a cluster (as a Cluster object) means that the cluster is used for any tasks that are added with can_run_on_cluster=True. Setting verbose to True will cause the time and the command to print whenever a new command is about to start. """ # Checks if self.__conditional != None: raise ValueError('Tasks already running') if len(self.inputs) == 0 and len(self.generators) == 0 and len(self.outputs) == 0 and len(self.cleanups) == 0 : return if (len(self.inputs) == 0 and len(self.generators) == 0) or (len(self.outputs) == 0 and len(self.cleanups) == 0): raise ValueError('Invalid set of tasks (likely cyclic)') prev_signal = None try: # Create basic variables and lock self._cluster = cluster self.__error = False self.__killing = False self.__conditional = Condition() # for locking access to Task.done, cpu_pressure, mem_pressure, next, last, log, and error self.__running = set() # Setup log done_tasks = self.__process_log() if exists(self.logname) else () self.__log = open(self.logname, 'w', 0) for k,v in self.settings.items(): self.__log.write("*"+k+"="+str(v)+"\n") # TODO: log overall inputs and outputs for dc in done_tasks: if verbose: print("Skipping " + dc[20:].strip()) self.__log.write(dc+"\n") if verbose and len(done_tasks) > 0: print('-' * 80) self._rusagelog = open(self.rusage_log, 'a', 1) if self.rusage_log else None # Calcualte the set of first and last tasks self.__calc_next() # These are the first tasks last = {self.outputs[f] for f in self.overall_outputs()} last |= self.cleanups if len(last) == 0: raise ValueError('Tasks are cyclic') self.__last = {t for t in last if not t.done} # Get the initial pressures self.__cpu_pressure = 0 self.__mem_pressure = get_mem_used_by_tree() + 1*MB # assume that the creation of threads and everything will add some extra pressure # Set a signal handler try: from signal import signal, SIGUSR1 prev_signal = signal(SIGUSR1, self.display_stats) except: pass # Keep running tasks in the tree until we have completed the root (which is self) with self.__conditional: while len(self.__last) != 0: # Get next task (or wait until all tasks or finished or an error is generated) while len(self.__last) > 0 and not self.__error: task = self.__next_task() if task != None: break self.__conditional.wait(30) # wait until we have some available [without the timeout CTRL+C does not work and we cannot see if memory is freed up on the system] if len(self.__last) == 0 or self.__error: break # Run it self.__running.add(task) t = Thread(target=self.__run, args=(task,)) t.daemon = True if verbose: print(strftime(Tasks.__time_format) + " Running " + str(task)) t.start() sleep(0) # make sure it starts # There was an error, let running tasks finish if self.__error and len(self.__running) > 0: write_error("Waiting for other tasks to finish running.\nYou can terminate them by doing a CTRL+C.") while len(self.__running) > 0: self.__conditional.wait(60) # wait until a task stops [without the timeout CTRL+C does not work] except KeyboardInterrupt: # Terminate and kill tasks write_error("Terminating running tasks") with self.__conditional: self.__killing = True for t in self.__running: try: t.terminate() except: pass secs = 0 while len(self.__running) > 0 and secs < 10: self.__conditional.wait(1) secs += 1 for t in self.__running: try: p.kill() except: pass finally: # Cleanup if prev_signal: signal(SIGUSR1, prev_signal) if hasattr(self, '__log'): self.__log.close() del self.__log if hasattr(self, '_rusagelog'): if self._rusagelog: self._rusagelog.close() del self._rusagelog if hasattr(self, '__cpu_pressure'): del self.__cpu_pressure if hasattr(self, '__mem_pressure'): del self.__mem_pressure if hasattr(self, '__running'): del self.__running if hasattr(self, '__next'): del self.__next self.__conditional = None del self._cluster del self.__error del self.__killing
# q.queue.clear() # lock.release() # print "Cleared" print str(head) ser2.write("####" + str(head) + "$$") except KeyboardInterrupt: # print files for f in files: # print str(f) # for f in files: if (str(f) == str(CVS_name)): shutil.move(f, dest) print 'Log files saved in folder ' + dest print "closing ports" t_bat.terminate() t_can.terminate() ser_batt.close() ser_can.close() except: print "Error: Main loop" # while True: # print q.get() # ser2.write(q.get()) # print("VEGA logging data ...") # time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # if count == 5: # ent = xbee.SendStr(data_raw.split(','))
class BountyBase: def __init__(self, api): self.api = api self.arr = [] def __getitem__(self, key): return self.arr[key] def __repr__(self): lenght = len(self.arr) checked = len(self.check(wipe=False)) bad = lenght - checked return 'BountyBase(len=%s, good=%s, bad=%s)' % (lenght, checked, bad) def report(self, cycle=True, background=True): if background: print('repors started') self.report_thread = Thread(target=self.report, kwargs={'background': False}) self.report_thread.start() else: while True: for bounty in self.arr: if bounty.is_report_need and bounty.send_report(): wait = randint(300, 600) print(f'[sleep: {wait}] report: {bounty}') sleep(wait) else: print('not report need:', bounty) sleep(randint(5, 10)) if cycle is False: return True def stop_report(self): self.report_thread.terminate() self.report_thread.join() self.report_thread = None def start(self, cycle=True, social=None): if not social: self.threads = dict() for key in Bounty.social_names.keys(): self.threads.update({ key: Thread(target=self.start, kwargs={ 'social': key, 'cycle': cycle }) }) self.threads[key].start() return None else: while True: for bounty in self.arr: if social in bounty.socials.keys(): print(bounty[social]) result = bounty[social].start() if result: wait = randint(abs(bounty[social].wait / 2), abs(bounty[social].wait * 1.5)) print( f'[action for {bounty[social]}] [wait: {wait}]' ) sleep(wait) else: sleep(randint(1, 3)) if cycle is False: print('[end of the', social, 'cycle]') return True else: print('[end of the %s cycle] [wait %s]' % (social, Bounty.social_names[social].wait)) sleep(Bounty.social_names[social].wait) print('[new', social, 'cycle]') def stop(self, social=None): if social: self.threads[social].terminate() self.threads[social].join() del self.threads[social] else: for key, social in self.threads.items(): social.terminate() social.join() self.threads = [] def check(self, wipe=True, date=True, links=True): checked = [] for bounty in self.arr: if date: check_date = bounty.is_actual_date else: check_date = True if links: checked_links = bounty.check_links(wipe=wipe) else: checked_links = True if check_date and checked_links: checked.append(bounty) if wipe: self.arr = checked return None return checked @property def dict(self): temp_dict = [] for bounty in self.arr: temp_dict.append(bounty.dict) return temp_dict def make(self, type='full'): self.raw = self.api.excel.spreadsheets().values().get( spreadsheetId=self.api.excel.LIST_ID, range=self.api.excel.LIST_RANGE).execute().get('values', []) if type is 'raw': return self.raw if type is 'dict': self.dict = [] self.arr = [] def get_field(num, inst=str, blank=None): try: if raw[num]: return inst(raw[num]) else: return blank except (IndexError, ValueError, TypeError): return blank for raw in self.raw: bounty_params = { 'report_link': 1, 'start': 2, 'end': 3, 'week_start': 4 } social_params = { 'twitter': { 'week_limit': 5, 'link': 7 }, 'facebook': { 'week_limit': 6, 'link': 8 }, 'telegram': { 'week_limit': None, 'link': 9 } } # id bounty_params['report_link'] = get_field( bounty_params['report_link']) # week_start add bounty_params['week_start'] = get_field( bounty_params['week_start'], int) # start date bounty_params['start'] = get_field(bounty_params['start']) if bounty_params['start']: try: bounty_params['start'] = datetime.strptime( bounty_params['start'].strip(), '%d.%m.%Y') except ValueError: bounty_params['start'] = None # end date bounty_params['end'] = get_field(bounty_params['end']) if bounty_params['end']: try: bounty_params['end'] = datetime.strptime( bounty_params['end'].strip(), '%d.%m.%Y') except ValueError: bounty_params['end'] = None # socials add for social, params in social_params.items(): # link params['link'] = get_field(params['link']) # limit params['week_limit'] = get_field(params['week_limit'], int) # make dict if type is 'dict': bounty_dict = bounty_params.copy() bounty_dict.update({'social_params': social_params}) self.dict_debug.append(bounty_dict) continue # Bounty add bounty = Bounty(self.api, **bounty_params) for social, params in social_params.items(): bounty.add_social(social, **params) self.arr.append(bounty)
class PiGear: """ PiGear is similar to CamGear but exclusively made to support various Raspberry Pi Camera Modules (such as OmniVision OV5647 Camera Module and Sony IMX219 Camera Module). To interface with these modules correctly, PiGear provides a flexible multi-threaded wrapper around complete picamera python library and provides us the ability to exploit its various features like `brightness, saturation, sensor_mode`, etc. effortlessly. :param (integer) camera_num: selects the camera module index that will be used by API. / Its default value is 0 and shouldn't be altered until unless / if you using Raspberry Pi 3/3+ compute module in your project along with multiple camera modules. / Furthermore, Its value can only be greater than zero, otherwise, it will throw ValueError for any negative value. :param (tuple) resolution: sets the resolution (width,height). Its default value is (640,480). :param (integer) framerate: sets the framerate. Its default value is 25. :param (string) colorspace: set colorspace of the video stream. Its default value is None. :param (dict) **options: sets parameter supported by PiCamera Class to the input video stream. / These attribute provides the flexibility to manipulate input raspicam video stream directly. / Parameters can be passed using this **option, allows you to pass key worded variable length of arguments to PiGear Class. :param (boolean) logging: set this flag to enable/disable error logging essential for debugging. Its default value is False. :param (integer) time_delay: sets time delay(in seconds) before start reading the frames. / This delay is essentially required for camera to warm-up. / Its default value is 0. """ def __init__(self, camera_num=0, resolution=(640, 480), framerate=30, colorspace=None, logging=False, time_delay=0, **options): try: import picamera from picamera.array import PiRGBArray from picamera import PiCamera except Exception as error: if isinstance(error, ImportError): # Output expected ImportErrors. raise ImportError( '[PiGear:ERROR] :: Failed to detect Picamera executables, install it with "pip3 install picamera" command.' ) else: #Handle any API errors raise RuntimeError( '[PiGear:ERROR] :: Picamera API failure: {}'.format(error)) # enable logging if specified self.__logging = False self.__logger = log.getLogger('PiGear') if logging: self.__logging = logging assert ( isinstance(framerate, (int, float)) and framerate > 5.0 ), "[PiGear:ERROR] :: Input framerate value `{}` is a Invalid! Kindly read docs.".format( framerate) assert ( isinstance(resolution, (tuple, list)) and len(resolution) == 2 ), "[PiGear:ERROR] :: Input resolution value `{}` is a Invalid! Kindly read docs.".format( resolution) if not (isinstance(camera_num, int) and camera_num >= 0): camera_num = 0 self.__logger.warning( "Input camera_num value `{}` is invalid, Defaulting to index 0!" ) # initialize the picamera stream at given index self.__camera = PiCamera(camera_num=camera_num) self.__camera.resolution = tuple(resolution) self.__camera.framerate = framerate if self.__logging: self.__logger.debug( "Activating Pi camera at index: {} with resolution: {} & framerate: {}" .format(camera_num, resolution, framerate)) #initialize framerate variable self.framerate = framerate #initializing colorspace variable self.color_space = None #reformat dict options = {k.strip(): v for k, v in options.items()} #define timeout variable default value(handles hardware failures) self.__failure_timeout = 2.0 #User-Defined parameter if options and "HWFAILURE_TIMEOUT" in options: #for altering timeout variable manually if isinstance(options["HWFAILURE_TIMEOUT"], (int, float)): if not (10.0 > options["HWFAILURE_TIMEOUT"] > 1.0): raise ValueError( '[PiGear:ERROR] :: `HWFAILURE_TIMEOUT` value can only be between 1.0 ~ 10.0' ) self.__failure_timeout = options[ "HWFAILURE_TIMEOUT"] #assign special parameter if self.__logging: self.__logger.debug( "Setting HW Failure Timeout: {} seconds".format( self.__failure_timeout)) del options["HWFAILURE_TIMEOUT"] #clean try: # apply attributes to source if specified for key, value in options.items(): setattr(self.__camera, key, value) # separately handle colorspace value to int conversion if not (colorspace is None): self.color_space = capPropId(colorspace.strip()) if self.__logging: self.__logger.debug( 'Enabling `{}` colorspace for this video stream!'. format(colorspace.strip())) except Exception as e: # Catch if any error occurred if self.__logging: self.__logger.exception(str(e)) # enable rgb capture array thread and capture stream self.__rawCapture = PiRGBArray(self.__camera, size=resolution) self.stream = self.__camera.capture_continuous(self.__rawCapture, format="bgr", use_video_port=True) #frame variable initialization self.frame = None try: stream = next(self.stream) self.frame = stream.array self.__rawCapture.seek(0) self.__rawCapture.truncate() #render colorspace if defined if not (self.frame is None and self.color_space is None): self.frame = cv2.cvtColor(self.frame, self.color_space) except Exception as e: self.__logger.exception(str(e)) raise RuntimeError( '[PiGear:ERROR] :: Camera Module failed to initialize!') # applying time delay to warm-up picamera only if specified if time_delay: time.sleep(time_delay) #thread initialization self.__thread = None #timer thread initialization(Keeps check on frozen thread) self.__timer = None self.__t_elasped = 0.0 #records time taken by thread # catching thread exceptions self.__exceptions = None # initialize termination flag self.__terminate = False def start(self): """ start the thread to read frames from the video stream and initiate internal timer """ #Start frame producer thread self.__thread = Thread(target=self.__update, name='PiGear', args=()) self.__thread.daemon = True self.__thread.start() #Start internal timer thread self.__timer = Thread(target=self.__timeit, name='PiTimer', args=()) self.__timer.daemon = True self.__timer.start() return self def __timeit(self): """ Keep checks on Thread excecution timing """ #assign current time self.__t_elasped = time.time() #loop until termainated while not (self.__terminate): #check for frozen thread if time.time() - self.__t_elasped > self.__failure_timeout: #log failure if self.__logging: self.__logger.critical("Camera Module Disconnected!") #prepare for clean exit self.__exceptions = True self.__terminate = True #self-terminate def __update(self): """ Update frames from stream """ #keep looping infinitely until the thread is terminated while True: #check for termination flag if self.__terminate: break try: #Try to iterate next frame from generator stream = next(self.stream) except Exception: #catch and save any exceptions self.__exceptions = sys.exc_info() break #exit #__update timer self.__t_elasped = time.time() # grab the frame from the stream and clear the stream in # preparation for the next frame frame = stream.array self.__rawCapture.seek(0) self.__rawCapture.truncate() #apply colorspace if specified if not (self.color_space is None): # apply colorspace to frames color_frame = None try: if isinstance(self.color_space, int): color_frame = cv2.cvtColor(frame, self.color_space) else: self.color_space = None if self.__logging: self.__logger.warning( 'Colorspace `{}` is not a valid colorspace!'. format(self.color_space)) except Exception as e: # Catch if any error occurred self.color_space = None if self.__logging: self.__logger.exception(str(e)) self.__logger.warning( 'Input colorspace is not a valid colorspace!') if not (color_frame is None): self.frame = color_frame else: self.frame = frame else: self.frame = frame # terminate processes if not (self.__terminate): self.__terminate = True # release picamera resources self.stream.close() self.__rawCapture.close() self.__camera.close() def read(self): """ return the frame """ #check if there are any thread exceptions if not (self.__exceptions is None): if isinstance(self.__exceptions, bool): #clear frame self.frame = None #notify user about hardware failure raise SystemError( '[PiGear:ERROR] :: Hardware failure occurred, Kindly reconnect Camera Module and restart your Pi!' ) else: #clear frame self.frame = None # re-raise error for debugging error_msg = "[PiGear:ERROR] :: Camera Module API failure occured: {}".format( self.__exceptions[1]) raise RuntimeError(error_msg).with_traceback( self.__exceptions[2]) # return the frame return self.frame def stop(self): """ Terminates the Read process """ if self.__logging: self.__logger.debug("Terminating PiGear Processes.") # make sure that the threads should be terminated self.__terminate = True #stop timer thread if not (self.__timer is None): self.__timer.join() #handle camera thread if not (self.__thread is None): #check if hardware failure occured if not (self.__exceptions is None) and isinstance( self.__exceptions, bool): # force release picamera resources self.stream.close() self.__rawCapture.close() self.__camera.close() #properly handle thread exit self.__thread.terminate() self.__thread.wait( ) #wait if still process is still processing some information self.__thread = None else: #properly handle thread exit self.__thread.join()
def function_handler(event): start_time = time.time() log_level = event['log_level'] cloud_logging_config(log_level) logger.debug("Action handler started") response_status = {'exception': False} response_status['host_submit_time'] = event['host_submit_time'] response_status['start_time'] = start_time context_dict = { 'python_version': os.environ.get("PYTHON_VERSION"), } config = event['config'] storage_config = extract_storage_config(config) call_id = event['call_id'] job_id = event['job_id'] executor_id = event['executor_id'] logger.info("Execution ID: {}/{}/{}".format(executor_id, job_id, call_id)) execution_timeout = event['execution_timeout'] logger.debug( "Set function execution timeout to {}s".format(execution_timeout)) status_key = event['status_key'] func_key = event['func_key'] data_key = event['data_key'] data_byte_range = event['data_byte_range'] output_key = event['output_key'] extra_env = event.get('extra_env', {}) response_status['call_id'] = call_id response_status['job_id'] = job_id response_status['executor_id'] = executor_id response_status['activation_id'] = os.environ.get('__OW_ACTIVATION_ID') # response_status['func_key'] = func_key # response_status['data_key'] = data_key # response_status['output_key'] = output_key # response_status['status_key'] = status_key try: if version.__version__ != event['pywren_version']: raise Exception("WRONGVERSION", "PyWren version mismatch", version.__version__, event['pywren_version']) # response_status['free_disk_bytes'] = free_disk_space("/tmp") custom_env = { 'PYWREN_CONFIG': json.dumps(config), 'PYWREN_REMOTE': 'TRUE', 'PYTHONPATH': "{}:{}".format(os.getcwd(), PYWREN_LIBS_PATH), 'PYTHONUNBUFFERED': 'True' } os.environ.update(custom_env) os.environ.update(extra_env) # if os.path.exists(JOBRUNNER_STATS_BASE_DIR): # shutil.rmtree(JOBRUNNER_STATS_BASE_DIR, True) jobrunner_stats_dir = os.path.join(STORAGE_BASE_DIR, executor_id, job_id, call_id) os.makedirs(jobrunner_stats_dir, exist_ok=True) jobrunner_stats_filename = os.path.join(jobrunner_stats_dir, 'jobrunner.stats.txt') jobrunner_config = { 'pywren_config': config, 'call_id': call_id, 'job_id': job_id, 'executor_id': executor_id, 'func_key': func_key, 'data_key': data_key, 'log_level': log_level, 'data_byte_range': data_byte_range, 'output_key': output_key, 'stats_filename': jobrunner_stats_filename } setup_time = time.time() response_status['setup_time'] = round(setup_time - start_time, 8) handler_conn, jobrunner_conn = Pipe() jobrunner = JobRunner(jobrunner_config, jobrunner_conn) logger.debug('Starting JobRunner process') local_execution = strtobool(os.environ.get('LOCAL_EXECUTION', 'False')) if local_execution: jrp = Thread(target=jobrunner.run) else: jrp = Process(target=jobrunner.run) jrp.daemon = True jrp.start() jrp.join(execution_timeout) logger.debug('JobRunner process finished') response_status['exec_time'] = round(time.time() - setup_time, 8) if jrp.is_alive(): # If process is still alive after jr.join(job_max_runtime), kill it try: jrp.terminate() except Exception: # thread does not have terminate method pass msg = ('Jobrunner process exceeded maximum time of {} ' 'seconds and was killed'.format(execution_timeout)) raise Exception('OUTATIME', msg) try: handler_conn.recv() except EOFError: logger.error( 'No completion message received from JobRunner process') logger.debug('Assuming memory overflow...') # Only 1 message is returned by jobrunner when it finishes. # If no message, this means that the jobrunner process was killed. # 99% of times the jobrunner is killed due an OOM, so we assume here an OOM. msg = 'Jobrunner process exceeded maximum memory and was killed' raise Exception('OUTOFMEMORY', msg) # print(subprocess.check_output("find {}".format(PYTHON_MODULE_PATH), shell=True)) # print(subprocess.check_output("find {}".format(os.getcwd()), shell=True)) if os.path.exists(jobrunner_stats_filename): with open(jobrunner_stats_filename, 'r') as fid: for l in fid.readlines(): key, value = l.strip().split(" ", 1) try: response_status[key] = float(value) except Exception: response_status[key] = value if key in [ 'exception', 'exc_pickle_fail', 'result', 'new_futures' ]: response_status[key] = eval(value) # response_status['server_info'] = get_server_info() response_status.update(context_dict) response_status['end_time'] = time.time() except Exception: # internal runtime exceptions print('----------------------- EXCEPTION !-----------------------', flush=True) traceback.print_exc(file=sys.stdout) print('----------------------------------------------------------', flush=True) response_status['end_time'] = time.time() response_status['exception'] = True pickled_exc = pickle.dumps(sys.exc_info()) pickle.loads( pickled_exc) # this is just to make sure they can be unpickled response_status['exc_info'] = str(pickled_exc) finally: store_status = strtobool(os.environ.get('STORE_STATUS', 'True')) dmpd_response_status = json.dumps(response_status) drs = sizeof_fmt(len(dmpd_response_status)) rabbitmq_monitor = config['pywren'].get('rabbitmq_monitor', False) if rabbitmq_monitor and store_status: rabbit_amqp_url = config['rabbitmq'].get('amqp_url') status_sent = False output_query_count = 0 params = pika.URLParameters(rabbit_amqp_url) queue = '{}-{}'.format(executor_id, job_id) while not status_sent and output_query_count < 5: output_query_count = output_query_count + 1 try: connection = pika.BlockingConnection(params) channel = connection.channel() channel.queue_declare(queue=queue, auto_delete=True) channel.basic_publish(exchange='', routing_key=queue, body=dmpd_response_status) connection.close() logger.info( "Execution status sent to rabbitmq - Size: {}".format( drs)) status_sent = True except Exception as e: logger.error("Unable to send status to rabbitmq") logger.error(str(e)) logger.info('Retrying to send status to rabbitmq...') time.sleep(0.2) if store_status: internal_storage = InternalStorage(storage_config) logger.info( "Storing execution stats - status.json - Size: {}".format(drs)) internal_storage.put_data(status_key, dmpd_response_status)
def main(argv): global t_list, g_run_flag, g_ext_log_file signal.signal(signal.SIGINT, signal_handler) try: log_file=LOG_FILE gw_ip='192.168.1.1' my_ip="" ssh_port=22 g_ext_log_file = False is_conn_map = False is_conn_map_sep_win = False conf_list=[] #check python version if (sys.version_info.major != 2) or (sys.version_info.minor != 7) or (sys.version_info.micro < 6): PRINTF("Error: python version must be 2.7.X where x>=6\n") return #get command line args argv_len = len(sys.argv) if argv_len == 1: printUsage() return else: for i in xrange(argv_len): arg_i = sys.argv[i].strip() if arg_i.startswith("-f="): g_ext_log_file = True log_file = arg_i.split("=")[1] elif arg_i.startswith("-map"): is_conn_map = True if "win" in arg_i: is_conn_map_sep_win = True elif arg_i.startswith("-conf="): conf_file_name = arg_i.split("=")[1] conf_i = imp.load_source('module.name', "./conf/" + conf_file_name) conf_i.CMD.append("-graphs") conf_list.append(conf_i.CMD) elif arg_i.startswith("-gw_ip="): gw_ip = arg_i.split("=")[1] elif arg_i.startswith("-my_ip="): my_ip = arg_i.split("=")[1] elif arg_i.startswith("-ssh_port="): ssh_port = int(arg_i.split("=")[1]) #add conn map if is_conn_map: map_arg = "-map" if is_conn_map_sep_win: map_arg += "_win" if len(conf_list) == 0: conf_list.append([map_arg]) else: for conf in conf_list: conf.append(map_arg) #Update CMD in conf_list CMD=["-f=%s" % log_file] CMD.append("-realtime=1.0,60") if g_ext_log_file: CMD.append("-ext_log_file") for i in range (0,len(conf_list)): if len(conf_list[i]) > 1: conf_list[i] = [conf_list[i][0]] + CMD + conf_list[i][1:] else: conf_list[i] = [conf_list[i][0]] + CMD #Server socket & beerocks_cli updates if not g_ext_log_file: #start server_socket t = Thread(target=socket_server, args=(log_file,)) t.start() t_list.append(t) #beerocks_cli updates (via ssh) time.sleep(3) t = Thread(target=ssh_start_beerocks_cli, args=(gw_ip, my_ip, ssh_port)) t.start() t_list.append(t) command = conf_list[0] time.sleep(randint(1,10)/10.0) init(command[:]) show() g_run_flag=False for t in t_list: t.join() except KeyboardInterrupt: PRINTF("") for t in t_list: try: t.terminate() except: pass g_run_flag=False sys.exit(0)
class AHRS: ''' The AHRS class provides an interface to AHRS capabilities of the KauaiLabs navX Robotics Navigation Sensor via I2C communications interfaces on the Raspberry Pi. The AHRS class enables access to basic connectivity and state information, as well as key 6-axis and 9-axis orientation information (yaw, pitch, roll, compass heading, fused (9-axis) heading and magnetic disturbance detection. Additionally, the ARHS class also provides access to extended information including linear acceleration, motion detection, rotation detection and sensor temperature. If used with the navX Aero, the AHRS class also provides access to altitude, barometric pressure and pressure sensor temperature data .. note:: This implementation does not provide access to the NavX via a serial port ''' NAVX_DEFAULT_UPDATE_RATE_HZ = 60 YAW_HISTORY_LENGTH = 10 DEFAULT_ACCEL_FSR_G = 2 DEFAULT_GYRO_FSR_DPS = 2000 QUATERNION_HISTORY_SECONDS = 5.0 def __init__(self, start_immediately=False, update_rate_hz=NAVX_DEFAULT_UPDATE_RATE_HZ): # Processed Data self.yaw = 0 self.pitch = 0 self.roll = 0 self.compass_heading = 0.0 self.world_linear_accel_x = 0.0 self.world_linear_accel_y = 0.0 self.world_linear_accel_z = 0.0 self.mpu_temp_c = 0.0 self.fused_heading = 0.0 self.altitude = 0.0 self.baro_pressure = 0.0 # self.is_moving = False # self.is_rotating = False self.baro_sensor_temp_c = 0.0 # self.altitude_valid = False # self.is_magnetometer_calibrated = False # self.magnetic_disturbance = False self.quaternion_w = 0 self.quaternion_x = 0 self.quaternion_y = 0 self.quaternion_z = 0 # Integrated Data self.vel_x = 0 self.vel_y = 0 self.vel_z = 0 self.disp_x = 0 self.disp_y = 0 self.disp_z = 0 # Raw Data self.raw_gyro_x = 0 self.raw_gyro_y = 0 self.raw_gyro_z = 0 self.raw_accel_x = 0 self.raw_accel_y = 0 self.raw_accel_z = 0 self.cal_mag_x = 0 self.cal_mag_y = 0 self.cal_mag_z = 0 # Configuration/Status self.update_rate_hz = update_rate_hz self.accel_fsr_g = self.DEFAULT_ACCEL_FSR_G self.gyro_fsr_dps = self.DEFAULT_GYRO_FSR_DPS self.capability_flags = 0 self.op_status = 0 self.sensor_status = 0 self.cal_status = 0 self.selftest_status = 0 # Board ID self.board_type = 0 self.hw_rev = 0 self.fw_ver_major = 0 self.fw_ver_minor = 0 self.last_sensor_timestamp = 0 self.last_update_time = 0.0 self.integrator = InertialDataIntegrator() self.yaw_angle_tracker = ContinuousAngleTracker() self.yaw_offset_tracker = OffsetTracker(self.YAW_HISTORY_LENGTH) self.quaternion_history = TimestampedQuaternionHistory() self.lock = Lock() self.io = I2C_IO(self, self.update_rate_hz) if start_immediately: self.start() def start(self): self.t = Thread(target=self.io.run, name="AHRS_I2C") self.t.start() def stop(self): self.running = False self.io.stop() def free(self): self.stop() self.t.join(timeout=5) if self.t.is_alive(): self.t.terminate() def response(self, child_conn): self.running = True if not hasattr(self, 't') or self.t is None or self.t.is_alive() is False: self.start() while self.running: if child_conn.poll(): cmd = child_conn.recv() else: time.sleep(.01) continue if cmd == ProcessCommands.TIME: child_conn.send(self.get_last_time_stamp()) elif cmd == ProcessCommands.YAW: child_conn.send(self.get_yaw()) elif cmd == ProcessCommands.PITCH: child_conn.send(self.get_pitch()) elif cmd == ProcessCommands.ROLL: child_conn.send(self.get_roll()) elif cmd == ProcessCommands.COMPASS_HEADING: child_conn.send(self.get_compass_heading()) elif cmd == ProcessCommands.ZERO_YAW: self.zero_yaw() child_conn.send("ok") elif cmd == ProcessCommands.IS_CALIBRATING: child_conn.send(self.is_calibrating()) elif cmd == ProcessCommands.IS_CONNECTED: child_conn.send(self.is_connected()) elif cmd == ProcessCommands.BYTE_COUNT: child_conn.send(self.get_byte_count()) elif cmd == ProcessCommands.UPDATE_COUNT: child_conn.send(self.get_update_count()) elif cmd == ProcessCommands.WORLD_LINEAR_ACCEL_X: child_conn.send(self.get_world_linear_accel_x()) elif cmd == ProcessCommands.WORLD_LINEAR_ACCEL_Y: child_conn.send(self.get_world_linear_accel_y()) elif cmd == ProcessCommands.WORLD_LINEAR_ACCEL_Z: child_conn.send(self.get_world_linear_accel_z()) elif cmd == ProcessCommands.BAROMETRIC_PRESSUE: child_conn.send(self.get_barometric_pressure()) elif cmd == ProcessCommands.ALTITUDE: child_conn.send(self.get_altitude()) elif cmd == ProcessCommands.FUSED_HEADING: child_conn.send(self.get_fused_heading()) elif cmd == ProcessCommands.QUATERNION_W: child_conn.send(self.get_quaternion_w()) elif cmd == ProcessCommands.QUATERNION_X: child_conn.send(self.get_quaternion_x()) elif cmd == ProcessCommands.QUATERNION_Y: child_conn.send(self.get_quaternion_y()) elif cmd == ProcessCommands.QUATERNION_Z: child_conn.send(self.get_quaternion_z()) elif cmd == ProcessCommands.RESET_DISPLACEMENT: self.reset_displacement() child_conn.send("ok") elif cmd == ProcessCommands.VELOCITY_X: child_conn.send(self.get_velocity_x()) elif cmd == ProcessCommands.VELOCITY_Y: child_conn.send(self.get_velocity_y()) elif cmd == ProcessCommands.VELOCITY_Z: child_conn.send(self.get_velocity_z()) elif cmd == ProcessCommands.DISPLACEMENT_X: child_conn.send(self.get_displacement_x()) elif cmd == ProcessCommands.DISPLACEMENT_Y: child_conn.send(self.get_displacement_y()) elif cmd == ProcessCommands.DISPLACEMENT_Z: child_conn.send(self.get_displacement_z()) elif cmd == ProcessCommands.TEMP_C: child_conn.send(self.getTempC()) elif cmd == ProcessCommands.IS_MOVING: child_conn.send(self.is_moving()) elif cmd == ProcessCommands.IS_ROTATING: child_conn.send(self.is_rotating()) elif cmd == ProcessCommands.ALTITUDE_VALID: child_conn.send(self.is_altitude_valid()) elif cmd == ProcessCommands.IS_MAGNETOMETER_CALIBRATED: child_conn.send(self.is_magnetometer_calibrated()) elif cmd == ProcessCommands.MAGNETIC_DISTURBANCE: child_conn.send(self.is_magnetic_disturbance()) elif cmd == ProcessCommands.STOP: self.stop() break elif cmd == ProcessCommands.FREE: self.free() break else: logger.warn("Unknown Command: {}".format(cmd)) child_conn.send("Unknown Command") # calculated properties @property def moving(self): return (self.sensor_status & AHRSProtocol.NAVX_SENSOR_STATUS_MOVING) != 0 @property def rotating(self): return (self.sensor_status & AHRSProtocol.NAVX_SENSOR_STATUS_YAW_STABLE) == 0 @property def altitude_valid(self): return (self.sensor_status & AHRSProtocol.NAVX_SENSOR_STATUS_ALTITUDE_VALID) != 0 @property def magnetometer_calibrated(self): return (self.sensor_status & AHRSProtocol.NAVX_CAL_STATUS_MAG_CAL_COMPLETE) != 0 @property def magnetic_disturbance(self): return (self.sensor_status & AHRSProtocol.NAVX_SENSOR_STATUS_MAG_DISTURBANCE) != 0 def get_last_time_stamp(self): ''' Returns the last time stamp reported by the sensor :return The last time stamp ''' return Time(self.last_sensor_timestamp, Time.s) def get_pitch(self): ''' Returns the current pitch value (in degrees, from -180 to 180) reported by the sensor. Pitch is a measure of rotation around the X Axis. :return The current pitch value in degrees (-180 to 180). ''' return Angle(self.pitch, Angle.degree) def get_roll(self): ''' Returns the current roll value (in degrees, from -180 to 180) reported by the sensor. Roll is a measure of rotation around the X Axis. :return The current roll value in degrees (-180 to 180). ''' return Angle(self.roll, Angle.degree) def get_yaw(self): ''' Returns the current yaw value (in degrees, from -180 to 180) reported by the sensor. Yaw is a measure of rotation around the Z Axis (which is perpendicular to the earth). Note that the returned yaw value will be offset by a user-specified offset value; this user-specified offset value is set by invoking the zero_yaw() method. :return The current yaw value in degrees (-180 to 180). ''' if (self._is_board_reset_supported()): return Angle(self.yaw, Angle.degree) else: yaw = self.yaw_offset_tracker.apply_offset(self.yaw) return Angle(yaw, Angle.degree) def get_compass_heading(self): ''' Returns the current tilt-compensated compass heading value (in degrees, from 0 to 360) reported by the sensor. Note that this value is sensed by a magnetometer, which can be affected by nearby magnetic fields (e.g., the magnetic fields generated by nearby motors). Before using this value, ensure that (a) the magnetometer has been calibrated and (b) that a magnetic disturbance is not taking place at the instant when the compass heading was generated. :return The current tilt-compensated compass heading, in degrees (0-360). ''' return Angle(self.compass_heading, Angle.degree) def zero_yaw(self): ''' Sets the user-specified yaw offset to the current yaw value reported by the sensor. This user-specified yaw offset is automatically subtracted from subsequent yaw values reported by the get_yaw() method. ''' if (self._is_board_reset_supported()): self.io.zero_yaw() else: self.yaw_offset_tracker.setOffset() def is_calibrating(self): ''' Returns true if the sensor is currently performing automatic gyro/accelerometer calibration. Automatic calibration occurs when the sensor is initially powered on, during which time the sensor should be held still, with the Z-axis pointing up (perpendicular to the earth). NOTE: During this automatic calibration, the yaw, pitch and roll values returned may not be accurate. Once calibration is complete, the sensor will automatically remove an internal yaw offset value from all reported values. :return Returns true if the sensor is currently automatically calibrating the gyro and accelerometer sensors. ''' return not ((self.cal_status & AHRSProtocol.NAVX_CAL_STATUS_IMU_CAL_STATE_MASK) == AHRSProtocol.NAVX_CAL_STATUS_IMU_CAL_COMPLETE) def is_connected(self): ''' Indicates whether the sensor is currently connected to the host computer. A connection is considered established whenever communication with the sensor has occurred recently. :returns: Returns true if a valid update has been recently received from the sensor. ''' return self.io.is_connected() def get_byte_count(self): ''' Returns the count in bytes of data received from the sensor. This could can be useful for diagnosing connectivity issues. If the byte count is increasing, but the update count (see :meth:`get_update_count`) is not, this indicates a software misconfiguration. :returns: The number of bytes received from the sensor. ''' return self.io.get_byte_count() def get_update_count(self): ''' Returns the count of valid updates which have been received from the sensor. This count should increase at the same rate indicated by the configured update rate. :returns: The number of valid updates received from the sensor. ''' return self.io.get_update_count() def get_world_linear_accel_x(self): ''' Returns the current linear acceleration in the X-axis (in G). World linear acceleration refers to raw acceleration data, which has had the gravity component removed, and which has been rotated to the same reference frame as the current yaw value. The resulting value represents the current acceleration in the x-axis of the body (e.g., the robot) on which the sensor is mounted. :return Current world linear acceleration in the X-axis (in G). ''' return Acceleration(self.world_linear_accel_x, Acceleration.G) def get_world_linear_accel_y(self): ''' Returns the current linear acceleration in the Y-axis (in G). World linear acceleration refers to raw acceleration data, which has had the gravity component removed, and which has been rotated to the same reference frame as the current yaw value. The resulting value represents the current acceleration in the Y-axis of the body (e.g., the robot) on which the sensor is mounted. :return Current world linear acceleration in the Y-axis (in G). ''' return Acceleration(self.world_linear_accel_y, Acceleration.G) def get_world_linear_accel_z(self): ''' Returns the current linear acceleration in the Z-axis (in G). World linear acceleration refers to raw acceleration data, which has had the gravity component removed, and which has been rotated to the same reference frame as the current yaw value. The resulting value represents the current acceleration in the Z-axis of the body (e.g., the robot) on which the sensor is mounted. :return Current world linear acceleration in the Z-axis (in G). ''' return Acceleration(self.world_linear_accel_z, Acceleration.G) def is_moving(self): ''' Indicates if the sensor is currently detecting motion, based upon the X and Y-axis world linear acceleration values. If the sum of the absolute values of the X and Y axis exceed a "motion threshold", the motion state is indicated. :return Returns true if the sensor is currently detecting motion. ''' return self.moving def is_rotating(self): ''' Indicates if the sensor is currently detecting yaw rotation, based upon whether the change in yaw over the last second exceeds the "Rotation Threshold." Yaw Rotation can occur either when the sensor is rotating, or when the sensor is not rotating AND the current gyro calibration is insufficiently calibrated to yield the standard yaw drift rate. :return Returns true if the sensor is currently detecting motion. ''' return self.rotating def get_barometric_pressure(self): ''' Returns the current barometric pressure, based upon calibrated readings from the onboard pressure sensor. This value is in units of millibar. NOTE: This value is only valid for a navX Aero. To determine whether this value is valid, see is_altitude_valid(). :return Returns current barometric pressure (navX Aero only). ''' return Pressure(self.baro_pressure, Pressure.mb) def get_altitude(self): ''' Returns the current altitude, based upon calibrated readings from a barometric pressure sensor, and the currently-configured sea-level barometric pressure [navX Aero only]. This value is in units of meters. NOTE: This value is only valid sensors including a pressure sensor. To determine whether this value is valid, see is_altitude_valid(). :return Returns current altitude in meters (as long as the sensor includes an installed on-board pressure sensor). ''' return Distance(self.altitude, Distance.m) def is_altitude_valid(self): ''' Indicates whether the current altitude (and barometric pressure) data is valid. This value will only be true for a sensor with an onboard pressure sensor installed. If this value is false for a board with an installed pressure sensor, this indicates a malfunction of the onboard pressure sensor. :return Returns true if a working pressure sensor is installed. ''' return self.altitude_valid def get_fused_heading(self): ''' Returns the "fused" (9-axis) heading. The 9-axis heading is the fusion of the yaw angle, the tilt-corrected compass heading, and magnetic disturbance detection. Note that the magnetometer calibration procedure is required in order to achieve valid 9-axis headings. The 9-axis Heading represents the sensor's best estimate of current heading, based upon the last known valid Compass Angle, and updated by the change in the Yaw Angle since the last known valid Compass Angle. The last known valid Compass Angle is updated whenever a Calibrated Compass Angle is read and the sensor has recently rotated less than the Compass Noise Bandwidth (~2 degrees). :return Fused Heading in Degrees (range 0-360) ''' return Angle(self.fused_heading, Angle.degree) def is_magnetic_disturbance(self): ''' Indicates whether the current magnetic field strength diverges from the calibrated value for the earth's magnetic field by more than the currently- configured Magnetic Disturbance Ratio. This function will always return false if the sensor's magnetometer has not yet been calibrated; see is_magnetometer_calibrated(). :return true if a magnetic disturbance is detected (or the magnetometer is uncalibrated). ''' return self.magnetic_disturbance def is_magnetometer_calibrated(self): ''' Indicates whether the magnetometer has been calibrated. Magnetometer Calibration must be performed by the user. Note that if this function does indicate the magnetometer is calibrated, this does not necessarily mean that the calibration quality is sufficient to yield valid compass headings. :return Returns true if magnetometer calibration has been performed. ''' return self.magnetometer_calibrated # Unit Quaternions def get_quaternion_w(self): ''' Returns the imaginary portion (W) of the Orientation Quaternion which fully describes the current sensor orientation with respect to the reference angle defined as the angle at which the yaw was last "zeroed". Each quaternion value (W,X,Y,Z) is expressed as a value ranging from -2 to 2. This total range (4) can be associated with a unit circle, since each circle is comprised of 4 PI Radians. For more information on Quaternions and their use, please see this <a href=https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation>definition</a>. :return Returns the imaginary portion (W) of the quaternion. ''' return Angle(self.quaternion_w / 16384.0, Angle.Q) def get_quaternion_x(self): ''' Returns the real portion (X axis) of the Orientation Quaternion which fully describes the current sensor orientation with respect to the reference angle defined as the angle at which the yaw was last "zeroed". Each quaternion value (W,X,Y,Z) is expressed as a value ranging from -2 to 2. This total range (4) can be associated with a unit circle, since each circle is comprised of 4 PI Radians. For more information on Quaternions and their use, please see this <a href=https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation>description</a>. :return Returns the real portion (X) of the quaternion. ''' return Angle(self.quaternion_x / 16384.0, Angle.Q) def get_quaternion_y(self): ''' Returns the real portion (X axis) of the Orientation Quaternion which fully describes the current sensor orientation with respect to the reference angle defined as the angle at which the yaw was last "zeroed". Each quaternion value (W,X,Y,Z) is expressed as a value ranging from -2 to 2. This total range (4) can be associated with a unit circle, since each circle is comprised of 4 PI Radians. For more information on Quaternions and their use, please see: https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation :return Returns the real portion (X) of the quaternion. ''' return Angle(self.quaternion_y / 16384.0, Angle.Q) def get_quaternion_z(self): ''' Returns the real portion (X axis) of the Orientation Quaternion which fully describes the current sensor orientation with respect to the reference angle defined as the angle at which the yaw was last "zeroed". Each quaternion value (W,X,Y,Z) is expressed as a value ranging from -2 to 2. This total range (4) can be associated with a unit circle, since each circle is comprised of 4 PI Radians. For more information on Quaternions and their use, please see: https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation :return Returns the real portion (X) of the quaternion. ''' return Angle(self.quaternion_z / 16384.0, Angle.Q) def reset_displacement(self): ''' Zeros the displacement integration variables. Invoke this at the moment when integration begins. ''' if (self._is_displacement_supported()): self.io.zero_displacement() else: self.integrator.reset_displacement() def update_displacement(self, accel_x_g, accel_y_g, update_rate_hz, is_moving): ''' Each time new linear acceleration samples are received, this function should be invoked. This function transforms acceleration in G to meters/sec^2, then converts this value to Velocity in meters/sec (based upon velocity in the previous sample). Finally, this value is converted to displacement in meters, and integrated. :return none. ''' self.integrator.update_displacement(accel_x_g, accel_y_g, update_rate_hz, is_moving) def get_velocity_x(self): ''' Returns the velocity (in meters/sec) of the X axis [Experimental]. NOTE: This feature is experimental. Velocity measures rely on integration of acceleration values from MEMS accelerometers which yield "noisy" values. The resulting velocities are not known to be very accurate. :return Current Velocity (in meters/sec). ''' if self._is_displacement_supported(): return Velocity(self.vel_x, Velocity.m_s) else: return Velocity(self.integrator.get_velocity_x(), Velocity.m_s) def get_velocity_y(self): ''' Returns the velocity (in meters/sec) of the Y axis [Experimental]. NOTE: This feature is experimental. Velocity measures rely on integration of acceleration values from MEMS accelerometers which yield "noisy" values. The resulting velocities are not known to be very accurate. :return Current Velocity (in meters/sec). ''' if self._is_displacement_supported(): return Velocity(self.vel_y, Velocity.m_s) else: return Velocity(self.integrator.get_velocity_y(), Velocity.m_s) def get_velocity_z(self): ''' Returns the velocity (in meters/sec) of the Z axis [Experimental]. NOTE: This feature is experimental. Velocity measures rely on integration of acceleration values from MEMS accelerometers which yield "noisy" values. The resulting velocities are not known to be very accurate. :return Current Velocity (in meters/sec). ''' if self._is_displacement_supported(): return Velocity(self.vel_z, Velocity.m_s) else: return Velocity(self.integrator.get_velocity_z(), Velocity.m_s) def get_displacement_x(self): ''' Returns the displacement (in meters) of the X axis since reset_displacement() was last invoked [Experimental]. NOTE: This feature is experimental. Displacement measures rely on double-integration of acceleration values from MEMS accelerometers which yield "noisy" values. The resulting displacement are not known to be very accurate, and the amount of error increases quickly as time progresses. :return Displacement since last reset (in meters). ''' if self._is_displacement_supported(): return Distance(self.disp_x, Distance.m) else: return Distance(self.integrator.get_displacement_x(), Distance.m) def get_displacement_y(self): ''' Returns the displacement (in meters) of the Y axis since reset_displacement() was last invoked [Experimental]. NOTE: This feature is experimental. Displacement measures rely on double-integration of acceleration values from MEMS accelerometers which yield "noisy" values. The resulting displacement are not known to be very accurate, and the amount of error increases quickly as time progresses. :return Displacement since last reset (in meters). ''' if self._is_displacement_supported(): return Distance(self.disp_y, Distance.m) else: return Distance(self.integrator.get_displacement_y(), Distance.m) def get_displacement_z(self): ''' Returns the displacement (in meters) of the Z axis since reset_displacement() was last invoked [Experimental]. NOTE: This feature is experimental. Displacement measures rely on double-integration of acceleration values from MEMS accelerometers which yield "noisy" values. The resulting displacement are not known to be very accurate, and the amount of error increases quickly as time progresses. :return Displacement since last reset (in meters). ''' if self._is_displacement_supported(): return Distance(self.disp_z, Distance.m) else: return Distance(self.integrator.get_displacement_z(), Distance.m) def get_temp(self): ''' Returns the current temperature (in degrees centigrade) reported by the sensor's gyro/accelerometer circuit. This value may be useful in order to perform advanced temperature- correction of raw gyroscope and accelerometer values. :return The current temperature (in degrees centigrade). ''' return Temperature(self.mpu_temp_c, Temperature.C) def get_board_yaw_axis(self): ''' Returns information regarding which sensor board axis (X,Y or Z) and direction (up/down) is currently configured to report Yaw (Z) angle values. NOTE: If the board firmware supports Omnimount, the board yaw axis/direction are configurable. For more information on Omnimount, please see: http://navx-mxp.kauailabs.com/navx-mxp/installation/omnimount/ :returns: The currently-configured board yaw axis/direction as a tuple of (up, axis). Up can be True/False, axis is 'x', 'y', or 'z') ''' yaw_axis_info = self.capability_flags >> 3 yaw_axis_info &= 7 if yaw_axis_info == AHRSProtocol.OMNIMOUNT_DEFAULT: up = True yaw_axis = 'z' else: up = True if yaw_axis_info & 0x01 != 0 else False yaw_axis_info >>= 1 if yaw_axis_info == 0: yaw_axis = 'x' elif yaw_axis_info == 1: yaw_axis = 'y' elif yaw_axis_info == 2: yaw_axis = 'z' return up, yaw_axis def get_firmware_version(self): ''' Returns the version number of the firmware currently executing on the sensor. To update the firmware to the latest version, please see: http://navx-mxp.kauailabs.com/navx-mxp/support/updating-firmware/ :return The firmware version in the format [MajorVersion].[MinorVersion] ''' return '%s.%s' % (self.fw_ver_major, self.fw_ver_minor) def get_quaternion_at_time(self, requested_timestamp): return self.quaternion_history.get(requested_timestamp) def get_yaw_at_time(self, requested_timestamp): match = self.quaternion_history.get(requested_timestamp) if match is not None: return match.get_yaw() return 0.0 def get_pitch_at_time(self, requested_timestamp): match = self.quaternion_history.get(requested_timestamp) if match is not None: return match.get_pitch() return 0.0 def get_roll_at_time(self, requested_timestamp): match = self.quaternion_history.get(requested_timestamp) if match is not None: return match.get_roll() return 0.0 # Internal API def _is_omni_mount_supported(self): return ((self.capability_flags & AHRSProtocol.NAVX_CAPABILITY_FLAG_OMNIMOUNT) != 0) def _is_board_reset_supported(self): return ((self.capability_flags & AHRSProtocol.NAVX_CAPABILITY_FLAG_YAW_RESET) != 0) def _is_displacement_supported(self): return ((self.capability_flags & AHRSProtocol.NAVX_CAPABILITY_FLAG_VEL_AND_DISP) != 0) def _is_ahrs_pos_time_stamp_supported(self): return ((self.capability_flags & AHRSProtocol.NAVX_CAPABILITY_FLAG_AHRSPOS_TS) != 0) def _set_yaw_pitch_roll(self, o): self.lock.acquire() self.__dict__.update(o.__dict__) self.lock.release() def _set_ahrs_pos_data(self, o, ts): self.lock.acquire() self.__dict__.update(o.__dict__) self.last_sensor_timestamp = ts if self.quaternion_history is not None: self.quaternion_history.add(self.quaternion_w, self.quaternion_x, self.quaternion_y, self.quaternion_z, self.last_sensor_timestamp) self.yaw_offset_tracker.update_history(self.yaw) self.yaw_angle_tracker.next_angle(self.get_yaw()) self.lock.release() def _set_raw_data(self, o, ts): self.lock.acquire() self.__dict__.update(o.__dict__) self.last_sensor_timestamp = ts self.lock.release() def _set_ahrs_data(self, o, ts): self.lock.acquire() self.__dict__.update(o.__dict__) self.last_sensor_timestamp = ts if self.quaternion_history is not None: self.quaternion_history.add(self.quaternion_w, self.quaternion_x, self.quaternion_y, self.quaternion_z, self.last_sensor_timestamp) self.yaw_offset_tracker.update_history(self.yaw) self._update_displacement(o.world_linear_accel_x, o.world_linear_accel_y, self.update_rate_hz, self.moving) self.yaw_angle_tracker.next_angle(self.get_yaw()) self.lock.acquire() def _set_board_id(self, o): self.lock.acquire() self.__dict__.update(o.__dict__) self.lock.release() def _set_board_state(self, o): self.lock.acquire() self.__dict__.update(o.__dict__) self.lock.release()
class NodeGenerator(Node): def __init__(self, network_address, loc): self.objects = {} self.init_network(network_address, loc) self.filename = ANALYSIS_FILE file = open(self.filename,"w") file.close() file = open('log.txt',"w") file.close() if TRACK: self.init_tracker() def init_network(self, network_address,loc): Node.__init__(self) self.loc = loc self.network_address = network_address self.neighbor_map = {} self.socket = None self.ip = IP self.listener = Thread(target=self.listen, name = "listen") self.heartbeat_generator = Thread(target=self.send_heartbeat, name= "send_heartbeat") def init_tracker(self): for file in glob.glob('./img/*.png')+glob.glob('./img/*.jpg'): img = {} img['path'] = file img['image'] = cv2.imread(file, cv2.CV_LOAD_IMAGE_GRAYSCALE) img['name'] = file.split(".")[1].split("/")[-1] img['history'] = [] self.objects[img['name']] = img self.detector = cv2.ORB(ORB_VALUE) self.descriptor = cv2.ORB(ORB_VALUE) self.matcher = cv2.DescriptorMatcher_create("BruteForce-Hamming") for object in self.objects.values(): kp = self.detector.detect(object['image']) object['kp'] = kp k_f, d_f = self.descriptor.compute(object['image'],kp) object['k_f'] = k_f object['d_f'] = d_f object['height'], object['width'] = object['image'].shape[:2] print object['name'], len(d_f) self.capture = cv2.VideoCapture(0) def write_to_file(self, msg): file = open(self.filename,"a") file.write(msg+'\n') file.close() def log(self, msg): file = open('log.txt','a') file.write(msg+'\n') file.close() def track(self): def filter_asymmetric(k_ftr, matches, matches2): sel_matches = [] for match1 in matches: for match2 in matches2: if k_ftr[match1.queryIdx] == k_ftr[match2.trainIdx] and k_scene[match1.trainIdx] == k_scene[match2.queryIdx]: sel_matches.append(match1) break return sel_matches def filter_distance(matches): dist = [m.distance for m in matches] thres_dist = (sum(dist) / len(dist)) * RATIO # keep only the reasonable matches sel_matches = [m for m in matches if m.distance < thres_dist] #print '#selected matches:%d (out of %d)' % (len(sel_matches), len(matches)) return sel_matches while True: self.all_matches = {} self.detected_objects = [] for object in self.objects.keys(): self.all_matches[object]=0 for frame in range(FRAMES): f, orig_img = self.capture.read() #img_scene = cv2.flip(orig_img, 1) img_scene = cv2.cvtColor(orig_img, cv2.COLOR_BGR2GRAY) view = img_scene #cv2.imshow("Track", view) try: kp_scene = self.detector.detect(img_scene) #print '#keypoints in Scene: %d' % (len(kp_scene)) k_scene, d_scene = self.descriptor.compute(img_scene, kp_scene) #print '#keypoints in Scene: %d' % ( len(d_scene)) for object in self.objects.values(): # match the keypoints try : matches = self.matcher.match(d_scene, object['d_f']) matches2 = self.matcher.match(object['d_f'], d_scene) # visualize the matches #print '#matches:', len(matches) dist = [m.distance for m in matches] #print 'distance: min: %.3f' % min(dist) #print 'distance: mean: %.3f' % (sum(dist) / len(dist)) #print 'distance: max: %.3f' % max(dist) """ filter matches """ matches = filter_distance(matches) matches2 = filter_distance(matches2) if len(matches)+len(matches2) < MATCH_PER_FRAME: raise Exception("Not enough matches") self.all_matches[object['name']] = self.all_matches[object['name']]+len(matches)+len(matches2) sel_matches = filter_asymmetric(object['k_f'], matches, matches2) """ localize object """ h_scene, w_scene = img_scene.shape[:2] h_ftr, w_ftr = object['height'], object['width'] ftr =[] scene = [] for m in sel_matches: scene.append(k_scene[m.queryIdx].pt) ftr.append(object['k_f'][m.trainIdx].pt) ftr = np.float32(ftr) scene = np.float32(scene) homography, mask = cv2.findHomography(ftr, scene, cv2.RANSAC) ftr_corners = np.float32([[0, 0], [w_ftr, 0], [w_ftr, h_ftr], [0, h_ftr]]).reshape(1, -1, 2) corners = np.int32( cv2.perspectiveTransform(ftr_corners, homography).reshape(-1, 2) ) """ visualization """ view = sp.zeros((max(h_scene, h_ftr), w_scene + w_ftr, 3), np.uint8) view[:h_scene, :w_scene, 0] = img_scene view[:h_ftr, w_scene:, 0] = object['image'] view[:, :, 1] = view[:, :, 0] view[:, :, 2] = view[:, :, 0] for m in sel_matches: # draw the keypoints color = tuple([sp.random.randint(0, 255) for _ in xrange(3)]) cv2.line(view, (int(k_scene[m.queryIdx].pt[0]), int(k_scene[m.queryIdx].pt[1])), (int(object['k_f'][m.trainIdx].pt[0] + w_scene), int(object['k_f'][m.trainIdx].pt[1])), color, 2) cv2.polylines(view, [np.int32([c+[w_scene,0] for c in ftr_corners])], True, (0, 255, 0), 2) cv2.polylines(view, [corners], True, (0, 255, 0), 2) except Exception: pass except Exception: pass view = cv2.resize(view, None, fx=0.5, fy=0.5, interpolation = cv2.INTER_CUBIC) #detected = cv2.resize(detected, None, fx=0.5, fy=0.5, interpolation = cv2.INTER_CUBIC) cv2.imshow("Track", view) #cv2.imshow("Detected", detected) self.log(json.dumps(self.all_matches)) for matched_object in self.all_matches: if self.all_matches[matched_object] > MATCH_PER_RUN: img = self.objects[matched_object]['image'] dim = (200,200) img = cv2.resize(img, dim,interpolation=cv2.INTER_AREA) self.detected_objects.append(img) #send data to neighbours msg = {'type': 'object_info', 'data': {'object': self.objects[matched_object]['name'], 'history' : self.objects[matched_object]['history']+[{'ts':str(datetime.datetime.now()).split('.')[0],'loc': self.loc}] }} self.broadcast_neighbours(json.dumps(msg)) self.write_to_file(json.dumps({'object': self.objects[matched_object]['name'], 'ts':str(datetime.datetime.now()).split('.')[0],'loc': self.loc})) if len(self.detected_objects) > 0: detected = np.concatenate(tuple(self.detected_objects), axis=1) cv2.imshow("Detected", detected) else: detected = sp.zeros((200, 400, 3), np.uint8) cv2.putText(detected,"Nothing Detected", (20,20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, 255) cv2.imshow("Detected", detected) def listen(self): # find a port that is free for listening and bind my listener self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.port = 5000 bind = False while not bind: try: # print self.port self.socket.bind((self.ip, self.port)) bind = True print("Client created on %s listening to port %s" % (self.ip, self.port)) except socket.error: self.port += 1 # tell my listening port and address to the network admin admin = socket.socket() admin.connect(self.network_address) admin.send(json.dumps({'type': 'intro', 'data': {'port': self.port, 'ip': self.ip, 'loc': self.loc}})) admin.close() while True: self.socket.listen(5) connection, address = self.socket.accept() self.process_message(connection.recv(BUFFER_SIZE)) def process_message(self, msg): try: message = json.loads(msg) if message['type'] == 'admin_broadcast': data = message['data'] print "BROADCAST: %s" % data if message['type']== 'neighbor_info': data=message['data'] print data self.neighbors = self.neighbors+data print "NEIGHBOURS : %s "% self.neighbors print "NEIGHBOR INFO: %s" % data if message['type'] == 'object_info': data = message['data'] print "" print "OBJECTDATA : %s" % data for entry in data['history']: entry['object']= data['object'] self.write_to_file(json.dumps(entry)) self.objects[data['object']]['history']= self.objects[data['object']]['history'] + data['history'] if message['type'] == 'heartbeat': data = message['data'] self.log("HEARTBEAT : %s" % str(data)) #print "HEARTBEAT : %s" % data #print "" except Exception: raise print 'Bad Message received: %s' % msg def message(self,address, msg): s = socket.socket() s.connect(address) s.send(msg) s.close() def broadcast_neighbours(self, message): for node in self.neighbors: #print "Broadcast to %s" % node try : self.message((node["ip"],node["port"]),message) except Exception: print "Cannot reach Neighbour %s" % node def send_heartbeat(self): while True: time.sleep(5) self.heartbeat() def heartbeat(self): self.broadcast_neighbours(json.dumps({'type': 'heartbeat', 'data': {'port': self.port, 'ip': self.ip, 'loc': self.loc}})) def stop(self): self.listener.terminate() sys.exit(0) def generate_report(self): name = raw_input("Enter the Object name to analyse:") if name not in self.objects.keys(): print "Cannot find object" return object = self.objects[name] history = object['history'] history.sort(key = lambda d: d['ts']) x_pts = [] y_pts = [] labels = [] for entry in history: x_pts.append(entry['loc'][0]) y_pts.append(entry['loc'][1]) labels.append(entry['ts']) plt.plot(x_pts,y_pts,marker='o', label="Trajectory of "+ name) def start(self): self.listener.start() self.heartbeat_generator.start() if TRACK: self.track() pass
count=0 past_load='' while True: count = count + 1 load = q.get() x = len(load) # print "length : "+str(x)+" Size : "+str(sys.getsizeof(q.get()))+" bytes Pht No : "+str(count)+"\n"+ q.get() q.get() send = "####,"+str(x)+","+str(count)+","+load+"!!" print send if load != past_load: ser2.write(send) past_load = load # board.getData(MultiWii.ATTITUDE) # head = board.attitude['heading'] except KeyboardInterrupt: print "closing ports" t_bat.terminate() t_can.terminate() ser_batt.close() ser_can.close() except: print "Error: Main loop" except : sys.exit(0) print "Error: Main"
def main(api_endpoint, credentials, project_id, device_model_id, device_id, device_config, lang, display, verbose, input_audio_file, output_audio_file, audio_sample_rate, audio_sample_width, audio_iter_size, audio_block_size, audio_flush_size, grpc_deadline, once, *args, **kwargs): """Samples for the Google Assistant API. Examples: Run the sample with microphone input and speaker output: $ python -m googlesamples.assistant Run the sample with file input and speaker output: $ python -m googlesamples.assistant -i <input file> Run the sample with file input and output: $ python -m googlesamples.assistant -i <input file> -o <output file> """ ############################################################################3 global updt_time, query, resp_text, mute, startmouth, TezHead, beep, faceFound, name2, onceface, facerec_en, keyboard_on # Setup logging. Kpx = 1 Kpy = 1 Ksp = 40 ## Head X and Y angle limits time.sleep(5) Xmax = 725 Xmin = 290 Ymax = 550 Ymin = 420 keyboard_on = False ## Initial Head position Xcoor = 511 Ycoor = 450 Facedet = 0 ## Time head wait turned touch_wait = 2 no_face_tm = time.time() face_det_tm = time.time() last_face_det_tm = time.time() touch_tm = 0 touch_samp = time.time() qbo_touch = 0 touch_det = False face_not_found_idx = 0 mutex_wait_touch = False faceFound = False onceface = False dist = 100 audio_response1 = '/home/pi/Reebo_Python/up.wav' wavep = wave.open(audio_response1, 'rb') audio_response2 = '/home/pi/Reebo_Python/HiTej.wav' wavep2 = wave.open(audio_response2, 'rb') facerec_en = False ############################################################################3 logging.basicConfig(level=logging.DEBUG if verbose else logging.INFO) # Load OAuth 2.0 credentials. try: with open(credentials, 'r') as f: credentials = google.oauth2.credentials.Credentials(token=None, **json.load(f)) http_request = google.auth.transport.requests.Request() credentials.refresh(http_request) except Exception as e: logging.error('Error loading credentials: %s', e) logging.error('Run google-oauthlib-tool to initialize ' 'new OAuth 2.0 credentials.') sys.exit(-1) # Create an authorized gRPC channel. grpc_channel = google.auth.transport.grpc.secure_authorized_channel( credentials, http_request, api_endpoint) logging.info('Connecting to %s', api_endpoint) # Configure audio source and sink. audio_device = None if input_audio_file: audio_source = audio_helpers.WaveSource( open(input_audio_file, 'rb'), sample_rate=audio_sample_rate, sample_width=audio_sample_width) else: audio_source = audio_device = (audio_device or audio_helpers.SoundDeviceStream( sample_rate=audio_sample_rate, sample_width=audio_sample_width, block_size=audio_block_size, flush_size=audio_flush_size)) if output_audio_file: audio_sink = audio_helpers.WaveSink(open(output_audio_file, 'wb'), sample_rate=audio_sample_rate, sample_width=audio_sample_width) else: audio_sink = audio_device = (audio_device or audio_helpers.SoundDeviceStream( sample_rate=audio_sample_rate, sample_width=audio_sample_width, block_size=audio_block_size, flush_size=audio_flush_size)) # Create conversation stream with the given audio source and sink. conversation_stream = audio_helpers.ConversationStream( source=audio_source, sink=audio_sink, iter_size=audio_iter_size, sample_width=audio_sample_width, ) if not device_id or not device_model_id: try: with open(device_config) as f: device = json.load(f) device_id = device['id'] device_model_id = device['model_id'] logging.info("Using device model %s and device id %s", device_model_id, device_id) except Exception as e: logging.warning('Device config not found: %s' % e) logging.info('Registering device') if not device_model_id: logging.error('Option --device-model-id required ' 'when registering a device instance.') sys.exit(-1) if not project_id: logging.error('Option --project-id required ' 'when registering a device instance.') sys.exit(-1) device_base_url = ( 'https://%s/v1alphapi@raspber2/projects/%s/devices' % (api_endpoint, project_id)) device_id = str(uuid.uuid1()) payload = { 'id': device_id, 'model_id': device_model_id, 'client_type': 'SDK_SERVICE' } session = google.auth.transport.requests.AuthorizedSession( credentials) r = session.post(device_base_url, data=json.dumps(payload)) if r.status_code != 200: logging.error('Failed to register device: %s', r.text) sys.exit(-1) logging.info('Device registered: %s', device_id) pathlib.Path(os.path.dirname(device_config)).mkdir(exist_ok=True) with open(device_config, 'w') as f: json.dump(payload, f) device_handler = device_helpers.DeviceRequestHandler(device_id) @device_handler.command('action.devices.commands.OnOff') def onoff(on): if on: logging.info('Turning device on') else: logging.info('Turning device off') @device_handler.command('com.example.commands.BlinkLight') def blink(speed, number): logging.info('Blinking device %s times.' % number) delay = 1 if speed == "slowly": delay = 2 elif speed == "quickly": delay = 0.5 for i in range(int(number)): logging.info('Device is blinking.') time.sleep(delay) #~ def findquery(): ############################# FACEREC THREAD ##################################################33 def facerec(): global name2 f = open("/home/pi/Reebo_Python/face_features.pkl", 'rb') details = pickle.load(f) # Initialize some variables face_locations = [] face_encodings = [] face_names = [] name2 = [] unknown_picture = fr.load_image_file("/home/pi/Reebo_Python/test.jpg") # Grab a single frame of video # frame = unknown_picture # Resize frame of video to 1/4 size for faster face recognition processing # small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses) # rgb_small_frame = small_frame[:, :, ::-1] # Find all the faces and face encodings in the current frame of video face_locations = fr.face_locations(unknown_picture) face_encodings = fr.face_encodings(unknown_picture, face_locations) print("{0} persons identified".format(len(face_locations))) face_names = [] for face_encoding in face_encodings: matches = fr.compare_faces(details['encodings'], face_encoding, 0.45) name = "Unknown" # If a match was found in known_face_encodings, just use the first one. if True in matches: first_match_index = matches.index(True) name = details["name"][first_match_index] face_names.append(name) print(face_names) for i in range(0, len(face_names)): name_temp = str(face_names[i]).replace('photos/', "") name_temp = str(name_temp).replace(']\'', "") name2.append(str(name_temp)) print name2 n = open("/home/pi/Reebo_Python/names.txt", 'w') for i in face_names: n.write(i + "\n") n.close() for (top, right, bottom, left), name in zip(face_locations, face_names): if not name: continue if name == "warner": cv2.rectangle(unknown_picture, (left, top), (right, bottom), (255, 0, 0), 2) cv2.rectangle(unknown_picture, (left, bottom - 25), (right, bottom), (255, 0, 0), 1) font = cv2.FONT_HERSHEY_DUPLEX cv2.putText(unknown_picture, name, (left + 6, bottom - 6), font, 0.5, (255, 255, 255), 1) else: cv2.rectangle(unknown_picture, (left, top), (right, bottom), (0, 0, 255), 2) cv2.rectangle(unknown_picture, (left, bottom - 25), (right, bottom), (0, 0, 255), 1) font = cv2.FONT_HERSHEY_DUPLEX cv2.putText(unknown_picture, name, (left + 6, bottom - 6), font, 0.5, (255, 255, 255), 1) cv2.imwrite("/home/pi/Reebo_Python/result.png", unknown_picture) def findFace(): global name2, faceFound, onceface, facerec_en, updt_time found_tm = time.time() onceface = False touch_samp = time.time() Xmax = 725 Xmin = 290 Ymax = 550 Ymin = 420 qbo_touch = 0 while True: #print("find face " + str(time.time())) try: faceFound = False # while not faceFound : # This variable is set to true if, on THIS loop a face has already been found # We search for a face three diffrent ways, and if we have found one already- # there is no reason to keep looking. #thread.start_new_thread(WaitForSpeech, ()) # WaitForSpeech() # ServoHome() Cface = [0, 0] t_ini = time.time() while time.time() - t_ini < 0.01: # wait for present frame t_ini = time.time() aframe = webcam.read()[ 1] #print "t: " + str(time.time()-t_ini) fface = frontalface.detectMultiScale( aframe, 1.3, 4, (cv2.cv.CV_HAAR_DO_CANNY_PRUNING + cv2.cv.CV_HAAR_FIND_BIGGEST_OBJECT + cv2.cv.CV_HAAR_DO_ROUGH_SEARCH), (60, 60)) pfacer = profileface.detectMultiScale( aframe, 1.3, 4, (cv2.cv.CV_HAAR_DO_CANNY_PRUNING + cv2.cv.CV_HAAR_FIND_BIGGEST_OBJECT + cv2.cv.CV_HAAR_DO_ROUGH_SEARCH), (80, 80)) if fface != (): # if we found a frontal face... for f in fface: # f in fface is an array with a rectangle representing a face faceFound = True face = f elif pfacer != (): # if we found a profile face... for f in pfacer: faceFound = True face = f if faceFound: updt_time = time.time() #facerec() if onceface == False: cv2.imwrite("/home/pi/Reebo_Python/test.jpg", aframe) onceface = True found_tm = time.time() x, y, w, h = face Cface = [ (w / 2 + x), (h / 2 + y) ] # we are given an x,y corner point and a width and height, we need the center TezHead.SetNoseColor(4) #print "face ccord: " + str(Cface[0]) + "," + str(Cface[1]) faceOffset_X = 160 - Cface[0] if (faceOffset_X > 20) | (faceOffset_X < -20): time.sleep(0.002) # acquire mutex TezHead.SetAngleRelative(1, faceOffset_X >> 1) # release mutex #wait for move time.sleep(0.05) #print "MOVE REL X: " + str(faceOffset_X >> 1) faceOffset_Y = Cface[1] - 120 if (faceOffset_Y > 20) | (faceOffset_Y < -20): time.sleep(0.002) # acquire mutex TezHead.SetAngleRelative(2, faceOffset_Y >> 1) # release mutex #wait for move time.sleep(0.05) if time.time() - found_tm > 0.5: TezHead.SetNoseColor(0) except Exception as e: print e pass try: current_touched = cap.touched() #last_touched = cap.touched() cap.set_thresholds(10, 6) # Check each pin's last and current state to see if it was pressed or released. i = 0 for i in [1, 11]: pin_bit = 1 << i # Each pin is represented by a bit in the touched value. A value of 1 # First check if transitioned from not touched to touched. if current_touched & pin_bit: #and not last_touched & pin_bit: print('{0} touched!'.format(i)) qbo_touch = int(i) ## # Next check if transitioned from touched to not touched. ## if not current_touched & pin_bit and last_touched & pin_bit: ## print('{0} released!'.format(i)) ## # Update last state and wait a short period before repeating. ## last_touched = current_touched #time.sleep(0.1) except: #print sys.exc_info() #print "error" pass if (time.time() - touch_samp > 0.5): # & (time.time() - last_face_det_tm > 3): touch_samp = time.time() #~ time.sleep(0.002) if qbo_touch in [1, 11]: if qbo_touch == 1: print("right") TezHead.SetServo(1, Xmax - 50, 100) time.sleep(0.002) TezHead.SetServo(2, Ymin - 5, 100) #thread.start_new_thread(WaitTouchMove, ()) # wait for begin touch move. time.sleep(1) qbo_touch = 0 elif qbo_touch == [2]: #~ time.sleep(0.002) TezHead.SetServo(2, Ymin - 5, 100) thread.start_new_thread(WaitTouchMove, ()) # wait for begin touch move. time.sleep(1) qbo_touch = 0 elif qbo_touch == 11: print("left") TezHead.SetServo(1, Xmin + 50, 100) time.sleep(0.002) TezHead.SetServo(2, Ymin - 5, 100) #thread.start_new_thread(WaitTouchMove, ()) # wait for begin touch move. time.sleep(1) qbo_touch = 0 def distance(): # set Trigger to HIGH GPIO.output(GPIO_TRIGGER, True) # set Trigger after 0.01ms to LOW time.sleep(0.00001) GPIO.output(GPIO_TRIGGER, False) StartTime = time.time() StopTime = time.time() # save StartTime while GPIO.input(GPIO_ECHO) == 0: StartTime = time.time() # save time of arrival while GPIO.input(GPIO_ECHO) == 1: StopTime = time.time() # time difference between start and arrival TimeElapsed = StopTime - StartTime # multiply with the sonic speed (34300 cm/s) # and divide by 2, because there and back distance = (TimeElapsed * 34300) / 2 return distance ################################## SOCKET THREAD ###################################################### def socket_thread(conn): print 'Socket.IO Thread Started.' def empid_received(): socket.emit('event-ask-cardno') print "ASK CARD NO" def cardno_received(): print "Card No received" conn.send(False) socket.on('event-empid-received', empid_received) socket.on('event-cardno-received', cardno_received) socket.wait() def findquery(parent_conn): global resp_text, mute, query, beep keyboard_on = False if resp_text == "Sorry, I can't help.": query = "Talk to Reebo" mute = True elif resp_text == "Alright! Say Cheese!": print "camera" aframe = webcam.read()[1] cv2.imwrite("/home/pi/reebo-backend/selfie.jpg", aframe) socket.emit('event-take-selfie') #mute=False elif resp_text.startswith("Can you please smile for the camera?"): mute = False beep = False print "BEEP" time.sleep(5) aframe = webcam.read()[1] cv2.imwrite("/home/pi/reebo-backend/selfie.jpg", aframe) socket.emit('event-take-selfie') query = "Say@#$: Thank you. Please enter your employee ID and card number" assistant.assist() socket.emit('event-ask-empid') keyboard_on = True print "KEYBOARD in findquery: ", keyboard_on keyboard_on = parent_conn.recv() query = "Say@#$: Thank You. You will be granted access shortly" mute = False beep = False if len(sys.argv) > 1: port = sys.argv[1] else: port = '/dev/serial0' try: # Open serial port ser = serial.Serial(port, baudrate=115200, bytesize=serial.EIGHTBITS, stopbits=serial.STOPBITS_ONE, parity=serial.PARITY_NONE, rtscts=False, dsrdtr=False, timeout=0) print "Open serial port sucessfully." print(ser.name) except Exception as e: print e print "Error opening serial port." sys.exit() try: cap = MPR121.MPR121() time.sleep(3) # if not cap.begin(): print('Error initializing MPR121. Check your wiring!') except Exception as e: print(e) pass TezHead = TezCmd.Controller(ser) TezHead.SetMouth(0x110E00) time.sleep(1) #TezHead.SetPid(1, 26, 12, 16) TezHead.SetPid(1, 26, 2, 16) #TezHead.SetPid(2, 26, 12, 16) TezHead.SetPid(2, 26, 2, 16) time.sleep(1) TezHead.SetServo(1, Xcoor, 100) TezHead.SetServo(2, Ycoor, 100) time.sleep(1) TezHead.SetNoseColor(0) webcam = cv2.VideoCapture( -1) # Get ready to start getting images from the webcam webcam.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 320) # I have found this to be about the highest- webcam.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 240) # resolution you'll want to attempt on the pi #webcam.set(cv2.CV_CAP_PROP_BUFFERSIZE, 2) # frame buffer storage if not webcam: print "Error opening WebCAM" sys.exit(1) #open = False frontalface = cv2.CascadeClassifier( "/home/pi/Documents/Python projects/haarcascade_frontalface_alt2.xml" ) # frontal face pattern detection profileface = cv2.CascadeClassifier( "/home/pi/Documents/Python projects/haarcascade_profileface.xml" ) # side face pattern detection #parent_conn, child_conn = Pipe() t1 = Thread(target=findFace) t1.start() t3 = Thread(target=facerec) parent_conn, child_conn = Pipe() socket_thd = Thread(target=socket_thread, args=(child_conn, )) socket_thd.start() with SampleAssistant(lang, device_model_id, device_id, conversation_stream, display, grpc_channel, grpc_deadline, device_handler) as assistant: # If file arguments are supplied: # exit after the first turn of the conversation. if input_audio_file or output_audio_file: assistant.assist() return # If no file arguments supplied: # keep recording voice requests using the microphone # and playing back assistant response using the speaker. # When the once flag is set, don't wait for a trigger. Otherwise, wait. wait_for_user_trigger = not once button_once = False #playsound('/home/pi/env/HiTej.wav') print "playsound" mute = True query = "Talk to Reebo" print query #################################################################################3 #~ query,mute=findquery() #####################################FIND QUERY AND MUTE#####################3 assistant.assist() mute = False query = "audio" time.sleep(1) updt_time = time.time() stream = conversation_stream num_frames = wavep.getnframes( ) # number of frames in audio response file resp_samples = wavep.readframes(num_frames) # get frames from wav file num_frames2 = wavep2.getnframes( ) # number of frames in audio response file resp_samples2 = wavep2.readframes( num_frames2) # get frames from wav file name = "" while True: #if wait_for_user_trigger: #logging.info('Press key') #x=raw_input() #~ stream.start_recording() # unelegant method to access private methods.. findquery(parent_conn) if mute == False or beep == True: print "beep" stream.start_playback() #~ stream.stop_recording() stream.write( resp_samples) # write response sample to output stream print "HI" stream.stop_playback() assistant.assist() beep = False query = "audio" mute = False #updt_time=time.time() print time.time() - updt_time dist = distance() #~ if dist<50: #~ print dist #~ updt_time=time.time() if time.time() - updt_time > 10: name2 = "" if onceface == True: facerec_en = False print "Thread Status", t3.is_alive() if t3.is_alive(): t3.terminate() t3.join(1) print "t3 terminated" print facerec_en onceface = False print("in loop") query = "audio" dist = distance() print faceFound while faceFound == False: time.sleep(0.1) #print "FACE FALSE" #~ if dist>60: #~ #mute=False #~ updt_time=time.time() #~ print query #~ while dist>60: #~ dist=distance() #~ time.sleep(0.1) #~ print dist #~ query="Hi" #~ print query #~ assistant.assist() #~ print ("playback") #~ socket.emit('event-robot-message',"Hi! Do you want some help ?") print "Thread Status", t3.is_alive() t3 = Thread(target=facerec) t3.start() #~ query="Talk to Tej" #~ mute=True #~ assistant.assist() #time.sleep(3) stream.start_playback() #~ stream.stop_recording() stream.write( resp_samples2) # write response sample to output stream socket.emit( 'event-robot-message', "Hi! My Name is Reebo. I\'ll be your personal assistant for today" ) stream.stop_playback() query = "Say:@#$: " if len(name2) >= 1: for i in range(0, len(name2)): if name2[i] != "" and name2[i] != "Unknown": query = query + " Hi " + str(name2[i]) + "!" query = query + "What can I do for you?" mute = False print query assistant.assist() #time.sleep(0.1) #~ stream.start_playback() #~ stream.stop_recording() #~ stream.write(resp_samples2) # write response sample to output stream #~ stream.stop_playback() #~ #query="Talk to Tej" #~ mute=True #~ assistant.assist() #~ updt_time= time.time() query = "audio" mute = False
class RepeatedCmd(object): __slots__ = set(('interval', 'queue', 'qlock', 'vlock', 'func', 'process', 'value', 'args', 'kwargs', 'paused', 'curinterval')) def __init__(self, interval, func, *args, **kwargs): self.curinterval = float(interval) self.interval = Value('f', self.curinterval) self.queue = Queue() self.vlock = Lock() self.qlock = Lock() self.func = func self.args = args self.kwargs = kwargs self.value = None self.process = None self.start() def setinterval(self, interval): if not self.alive(): raise ProcessHaltedError(notalive) self.curinterval = float(interval) self.interval.value = self.curinterval def getvalue(self): if not self.alive(): result = self.getcurrentvalue() self.start() return result self.qlock.acquire() if self.value is None or not self.queue.empty(): while(not self.queue.empty()): self.value = self.queue.get() self.qlock.release() return self.value def getcurrentvalue(self): self.vlock.acquire() self.qlock.acquire() if self.value is None or not self.queue.empty(): while(not self.queue.empty()): self.queue.get() self.qlock.release() self.value = self.func(*self.args, **self.kwargs) self.vlock.release() return self.value def alive(self): return ( self.process is not None and self.process.is_alive() and self.interval.value > 0.0) def join(self): if ( self.process is not None and self.process.is_alive() and self.interval.value <= 0.0): self.process.join() def run(self): # Override default signal vim handlers with system default behavior # (i.e. terminate or ignore), especially SIGTERM. Without this hack # process.terminate() may leave the process alive. Bad, I do not know # why it leaves it alive only in some limited set of cases. use_default_signal_handlers() while self.interval.value > 0.0: starttime = time.clock() self.vlock.acquire() value = self.func(*self.args, **self.kwargs) self.vlock.release() self.qlock.acquire() # If I only knew the size of func() output I would have used # Value() while(not self.queue.empty()): self.queue.get() self.queue.put(value) self.qlock.release() try: time.sleep(self.interval.value-(time.clock()-starttime)) except Exception: # Work when interval-elapsed results in negative value. pass def start(self): if self.alive(): return self.join() self.process = Process(target=self.run) self.process.start() def stop(self): if not self.alive(): return # For some reason process.terminate() sometimes may not seem to work. # This is a workaround. Seems it is no longer needed with # self.process.join(), just keeping it here for multiprocessing. # For threading this is the only way to terminate thread (use old # implementation based on sequence of timers?) self.interval.value = -1.0 try: self.process.terminate() # Anti-zombie code self.process.join() except AttributeError: # Threads do not have .terminate method pass pause = stop resume = start __del__ = stop
class Node(): ips = [] def __init__(self, _id): self.id = int(_id) self.ip = Node.ips[self.id] self.lock = Lock() self.listener = SocketServer.TCPServer(('0.0.0.0', 6000), MyTCPHandler) self.listener.node = self self.thread = Thread(target=self.listener.serve_forever) self.thread.start() self.entry_set = calendar.EntrySet() self.init_calendar() self.log = open("log.dat", "a+") self.last = None if os.path.isfile("log.dat"): self.entry_set.create_from_log(self) def init_calendar(self): self.table = TimeTable(len(Node.ips)) self.events = [] def kill(): print('killin') self.listener.shutdown() # Expect data in the form: # {'table': <serialized table>, 'events': <array of events>} def receive(self, raw): data = json.loads(raw) print(self.table.table) print(data) if data['type'] == "failure": self.rec_failure(data) else: new_table = TimeTable.load(json.loads(data['table']), len(Node.ips)) events = data['events'] new_events = [] for event in events: event = Event.load(json.loads(event)) if event.entry: event.entry = Entry.load(event.entry) new_events.append(event) # For all events this node doesn't have, make modifications for event in new_events: if not self.has_event(event, self.id): res = event.apply(self.entry_set, self) if res: self.events.append(event) else: if event.type == MessageTypes.Insert: self.send_failure(event) self.table.sync(new_table, self.id, data['node_id']) print(self.table.table) def send(self, _id, event=None): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: data = "data" # print("Sending Data from client") # Connect to server and send data sock.settimeout(3) sock.connect((Node.ips[_id], 6000)) sock.sendall(event) # Receive data from the server and shut down received = sock.recv(1024) # Add To EntrySet except: # Node Down cancel conflict if not event == None: print("Failed to connect to node: " + str(_id)) d = json.loads(event) dd = json.loads(d['events'][0]) event = Event.load(dd) event.entry = Entry.load(event.entry) self.delete_entry(event.entry, [_id]) pass finally: sock.close() def send_failure(self, event): #grab id from event print("Sending Failure command") data = { 'node_id': self.id, 'type': 'failure', 'event': event.to_JSON() } self.send(event.node, json.dumps(data)) def rec_failure(self, data): event = Event.load(json.loads(data['event'])) event.entry = Entry.load(event.entry) self.delete_entry(event.entry) # Check if a node has a certain event def has_event(self, event, node_id): return self.table.get(node_id, event.node) >= event.time def send_to_node(self, node_id): # Don't send anything if the node is this if node_id == self.id: return partial = [] for event in self.events: if not isinstance(event, Event): continue if not self.has_event(event, node_id): partial.append(event.to_JSON()) data = { 'type': 'sync', 'node_id': self.id, 'table': self.table.to_JSON(), 'events': partial, } self.send(node_id, json.dumps(data)) def add_entry(self, entry): event = Event(MessageTypes.Insert, time.time(), self.id, entry) self.table.update(self.id, time.time() + 0.1) event.apply(self.entry_set, self) self.events.append(event) for id in entry.participants: if not id == self.id: self.send_to_node(id) def delete_entry(self, entry, exclude=[]): event = Event(MessageTypes.Delete, time.time(), self.id, entry) self.table.update(self.id, time.time() + 0.1) event.apply(self.entry_set, self) self.events.append(event) for id in entry.participants: if not id == self.id: if not id in exclude: self.send_to_node(id) def kill_thread(self): self.thread.terminate()
class NumpyVisdomLogger(AbstractLogger): """ Visual logger, inherits the AbstractLogger and plots/ logs numpy arrays/ values on a Visdom server. """ def __init__(self, exp_name="main", server="http://localhost", port=8080, auto_close=True, auto_start=False, auto_start_ports=(8080, 8000), **kwargs): """ Creates a new NumpyVisdomLogger object. Args: name: The name of the visdom environment server: The address of the visdom server port: The port of the visdom server auto_close: Close all objects and kill process at the end of the python script auto_start: Flag, if it should try to start a visdom server on the given ports auto_start_ports: Ordered list of ports, to try to start a visdom server on (only on the first available port) """ super(NumpyVisdomLogger, self).__init__(**kwargs) if auto_start: auto_port = start_visdom(auto_start_ports) if auto_port != -1: port = auto_port server = "http://localhost" self.name = exp_name self.server = server self.port = port self.vis = ExtraVisdom(env=self.name, server=self.server, port=self.port) self._value_counter = defaultdict(dict) self._3d_histograms = dict() self._queue = Queue() self._process = Process(target=self.__show, args=(self._queue, )) if auto_close: # atexit.register(self.close_all) if not IS_WINDOWS: atexit.register(self.exit) atexit.register(self.save_vis) self._process.start() def __show(self, queue): """ Loop for the internal process to process all visualization tasks Args: queue: queue with all visualization tasks """ while True: vis_task = queue.get() try: show_fn = self.show_funcs[vis_task["type"]] show_fn(self, **vis_task) except Exception as e: error = sys.exc_info()[0] msg = traceback.format_exc() print("Error {}: {}".format(error, msg)) @convert_params def show_image(self, image, name=None, title=None, caption=None, env_appendix="", opts=None, **kwargs): """ Displays an image in a window/pane at the visdom server Args: image: The image array to be displayed name: The name of the image window title: The title of the image window caption: The of the image, displayed in the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "image", "image": image, "name": name, "title": title, "caption": caption, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_image(self, image, name=None, title=None, caption=None, env_appendix="", opts=None, **kwargs): """ Internal show_image method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} opts = opts.copy() opts.update(dict(title=title, caption=caption)) win = self.vis.image(img=image, win=name, env=self.name + env_appendix, opts=opts) return win @convert_params def show_images(self, images, name=None, title=None, caption=None, env_appendix="", opts=None, **kwargs): """ Displays multiple images in a window/pane at a visdom server Args: images: The image array to be displayed name: The name of the window title: The title of the image window caption: The of the image, displayed in the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "images", "images": images, "name": name, "title": title, "caption": caption, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_images(self, images, name=None, title=None, caption=None, env_appendix="", opts=None, **kwargs): """ Internal show_images method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} else: if 'nrow' in opts.keys(): nrow = opts['nrow'] else: nrow = 8 # as defined in function opts = opts.copy() opts.update(dict(title=title, caption=caption)) win = self.vis.images( tensor=images, win=name, env=self.name + env_appendix, opts=opts, # nrow=nrow ) return win @convert_params def show_value(self, value, name=None, counter=None, tag=None, show_legend=True, env_appendix="", opts=None, **kwargs): """ Creates a line plot that is automatically appended with new values and plots it to a visdom server. Args: value: Value to be plotted / appended to the graph (y-axis value) name: The name of the window counter: counter, which tells the number of the sample (with the same name) (x-axis value) tag: Tag, grouping similar values. Values with the same tag will be plotted in the same plot show_legend (bool): Flag, if it should display a legend env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "value", "value": value, "name": name, "counter": counter, "tag": tag, "show_legend": show_legend, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_value(self, value, name=None, counter=None, tag=None, show_legend=True, env_appendix="", opts=None, **kwargs): """ Internal show_value method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} value_dim = 1 if isinstance(value, (list, tuple, np.ndarray)): value_dim = len(value) value = np.asarray([value]) else: value = np.asarray([value]) if tag is None: tag = "" if name is not None: tag = name if "showlegend" not in opts and show_legend: opts["showlegend"] = True up_str = None if tag is not None and tag in self._value_counter: up_str = "append" if tag is not None and tag in self._value_counter and name in self._value_counter[ tag]: if counter is None: self._value_counter[tag][name] += 1 else: self._value_counter[tag][ name] += counter - self._value_counter[tag][name] else: if counter is None: counter = 0 if value_dim == 1: self._value_counter[tag][name] = np.array([counter]) else: self._value_counter[tag][name] = np.array([[counter] * value_dim]) opts = opts.copy() opts.update(dict(title=tag, )) display_name = tag if value_dim != 1: display_name = None win = self.vis.line(Y=value, X=self._value_counter[tag][name], win=tag, name=name, update=up_str, env=self.name + env_appendix, opts=opts) return win @convert_params def show_text(self, text, name=None, env_appendix="", opts=None, **kwargs): """ Displays a text in a visdom window Args: text: The text to be displayed name: The name of the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "text", "text": text, "name": name, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_text(self, text, name=None, env_appendix="", opts=None, **kwargs): """ Internal show_text method, called by the internal process. This function does all the magic. """ text = text.replace("\n", "<br>") if opts is None: opts = {} win = self.vis.text(text=text, win=name, env=self.name + env_appendix, opts=opts) return win @convert_params def show_progress(self, num, total=None, name=None, env_appendix="", opts=None, **kwargs): """ Shows the progress as a pie chart. Args: num: Current progress. Either a relative value (0 <= num <= 1) or a absolute value if total is given ( but has to be smaller than total) total: This if the total number of iterations. name: The name of the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "progress", "num": num, "total": total, "name": name, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_progress(self, num, total=None, name=None, env_appendix="", opts=None, **kwargs): """ Internal show_progress method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} if total is None: if 0 <= num <= 1: total = 1000. num = 1000. * num else: raise AttributeError( "Either num has to be a ratio between 0 and 1 or give a valid total number" ) else: if num > total: raise AttributeError("Num has to be smaller than total") if name is None: name = "progress" x = np.asarray([num, total - num]) opts = opts.copy() opts.update(dict(legend=['Done', 'To-Do'], title="Progress")) win = self.vis.pie(X=x, win=name, env=self.name + env_appendix, opts=opts) return win @convert_params def show_histogram(self, array, name=None, bins=30, env_appendix="", opts=None, **kwargs): """ Displays the histogramm of an array. Args: array: The array the histogram is calculated of name: The name of the window bins: Number of bins (== bars) in the histogram env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "histogram", "array": array, "bins": bins, "name": name, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_histogram(self, array, name=None, bins=30, env_appendix="", opts=None, **kwargs): """ Internal show_histogram method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} opts = opts.copy() opts.update(dict(title=name, numbins=bins)) win = self.vis.histogram(X=array, win=name, env=self.name + env_appendix, opts=opts) return win @convert_params def show_histogram_3d(self, array, name, bins=50, env_appendix="", opts=None, **kwargs): """ Displays a history of histograms as consequtive lines in a 3d space (similar to tensorflow) Args: array: New sample of the array that should be plotted (i.e. results in one line of the 3d histogramm) name: The name of the window bins: Number of bins in the histogram env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "histogram_3d", "array": array, "bins": bins, "name": name, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_histogram_3d(self, array, name, bins=50, env_appendix="", opts=None, **kwargs): """ Internal show_histogram_3d method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} if name not in self._3d_histograms: self._3d_histograms[name] = [] self._3d_histograms[name].append(array) if len(self._3d_histograms[name]) > 50: n_histo = len(self._3d_histograms[name]) - 20 every_n = n_histo // 30 + 1 x = self._3d_histograms[name][:-20][ 0::every_n] + self._3d_histograms[name][-20:] else: x = self._3d_histograms[name] opts = opts.copy() opts.update(dict(title=name, numbins=bins)) win = self.vis.histogram_3d(X=x, win=name, env=self.name + env_appendix, opts=opts) return win @convert_params def show_barplot(self, array, legend=None, rownames=None, name=None, env_appendix="", opts=None, **kwargs): """ Displays a bar plot from an array Args: array: array of shape NxM where N is the nomber of rows and M is the number of elements in the row. legend: list of legend names. Has to have M elements. rownames: list of row names. Has to have N elements. name: The name of the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "barplot", "array": array, "legend": legend, "rownames": rownames, "name": name, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_barplot(self, array, legend=None, rownames=None, name=None, env_appendix="", opts=None, **kwargs): """ Internal show_barplot method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} opts = opts.copy() opts.update( dict(stacked=False, legend=legend, rownames=rownames, title=name)) win = self.vis.bar(X=array, win=name, env=self.name + env_appendix, opts=opts) return win @convert_params def show_lineplot(self, y_vals, x_vals=None, name=None, env_appendix="", show_legend=True, opts=None, **kwargs): """ Displays (multiple) lines plot, given values Y (and optional the corresponding X values) Args: y_vals: Array of shape MxN , where M is the number of points and N is the number of different line x_vals: Has to have the same shape as Y: MxN. For each point in Y it gives the corresponding X value (if not set the points are assumed to be equally distributed in the interval [0, 1] ) name: The name of the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "lineplot", "x_vals": x_vals, "y_vals": y_vals, "name": name, "show_legend": show_legend, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_lineplot(self, y_vals, x_vals=None, name=None, env_appendix="", show_legend=True, opts=None, **kwargs): """ Internal show_lineplot method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} opts = opts.copy() opts.update(dict(title=name, )) if "showlegend" not in opts and show_legend: opts["showlegend"] = True win = self.vis.line(X=x_vals, Y=y_vals, win=name, env=self.name + env_appendix, opts=opts) return win @convert_params def show_boxplot(self, x_vals, name=None, env_appendix="", opts=None, **kwargs): """ Displays a box plot, given values X Args: x_vals: Array of shape MxN , where M is the number of points and N are the number of groups name: The name of the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "boxplot", "x_vals": x_vals, "name": name, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_boxplot(self, x_vals, name=None, env_appendix="", opts=None, **kwargs): """ Internal show_lineplot method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} opts = opts.copy() opts.update(dict(title=name, )) win = self.vis.boxplot(X=x_vals, win=name, env=self.name + env_appendix, opts=opts) return win @convert_params def show_surfaceplot(self, x_vals, name=None, env_appendix="", opts=None, **kwargs): """ Displays a surface plot given values X Args: x_vals: Array of shape MxN name: The name of the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "surfaceplot", "x_vals": x_vals, "name": name, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_surfaceplot(self, x_vals, name=None, env_appendix="", opts=None, **kwargs): """ Internal show_surfaceplot method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} opts.update( dict(title=name, colormap='Viridis', xlabel='X', ylabel='Y')) opts = opts.copy() win = self.vis.surf( X=x_vals, win=name, env=self.name + env_appendix, opts=opts, ) return win @convert_params def show_contourplot(self, x_vals, name=None, env_appendix="", opts=None, **kwargs): """ Displays a contour plot Args: x_vals: Array of shape MxN name: The name of the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "contourplot", "x_vals": x_vals, "name": name, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_contourplot(self, x_vals, name=None, env_appendix="", opts=None, **kwargs): """ Internal show_contourplot method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} opts.update( dict(title=name, colormap='Viridis', xlabel='feature', ylabel='batch')) opts = opts.copy() win = self.vis.contour( X=x_vals, win=name, env=self.name + env_appendix, opts=opts, ) return win @convert_params def show_scatterplot(self, array, labels=None, name=None, env_appendix="", opts=None, **kwargs): """ Displays a scatter plots, with the points given in array Args: array: A 2d array with size N x dim, where each element i \in N at X[i] results in a a 2d (if dim = 2)/ 3d (if dim = 3) point. labels: For each point a int label (starting from 1) can be given. Has to be an array of size N. name: The name of the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "scatterplot", "array": array, "labels": labels, "name": name, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_scatterplot(self, array, labels=None, name=None, env_appendix="", opts=None, **kwargs): """ Internal show_scatterplot method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} opts.update(dict(title=name, )) win = self.vis.scatter(X=array, Y=labels, win=name, env=self.name + env_appendix, opts=opts) return win @convert_params def show_piechart(self, array, name=None, env_appendix="", opts=None, **kwargs): """ Displays a pie chart. Args: array: Array of positive integers. Each integer will be presented as a part of the pie (with the total as the sum of all integers) name: The name of the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "piechart", "array": array, "name": name, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_piechart(self, array, name=None, env_appendix="", opts=None, **kwargs): """ Internal show_piechart method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} opts.update(dict(title=name)) win = self.vis.pie(X=array, win=name, env=self.name + env_appendix, opts=opts) return win @convert_params def show_svg(self, svg, name=None, env_appendix="", opts=None, **kwargs): """ Displays a svg file. Args: svg: Filename of the svg file which should be displayed name: The name of the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "svg", "svg": svg, "name": name, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_svg(self, svg, name=None, env_appendix="", opts=None, **kwargs): """ Internal show_svg method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} with open(svg, 'r') as fileobj: svgstr = fileobj.read() opts.update(dict(title=name)) win = self.vis.svg(svgstr=svgstr, win=name, env=self.name + env_appendix, opts=opts) return win def show_values(self, val_dict): """A util function for multiple values. Simple plots all values in a dict, there the window name is the key in the dict and the plotted value is the value of a dict (Simply calls the show_value function). Args: val_dict: Dict with key, values pairs which will be plotted """ for name, value in val_dict: self.show_value(value, name) @convert_params def add_to_graph(self, y_vals, x_vals=None, name=None, legend_name=None, append=True, env_appendix="", opts=None, **kwargs): """ Displays (multiple) lines plot, given values Y (and optional the corresponding X values) Args: y_vals: Array of shape MxN , where M is the number of points and N is the number of different line x_vals: Has to have the same shape as Y: MxN. For each point in Y it gives the corresponding X value (if not set the points are assumed to be equally distributed in the interval [0, 1] ) name: The name of the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "add", "x_vals": x_vals, "y_vals": y_vals, "name": name, "legend_name": legend_name, "append": append, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __add_to_graph(self, y_vals, x_vals=None, name=None, legend_name=None, append=True, env_appendix="", opts=None, **kwargs): """ Internal show_lineplot method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} opts.update(dict(title=name, )) win = self.vis.updateTrace(X=x_vals, Y=y_vals, win=name, name=legend_name, append=append, env=self.name + env_appendix, opts=opts) return win @convert_params def show_matplot_plt(self, plt, name=None, title=None, caption=None, env_appendix="", opts=None, **kwargs): """ Displays an matplotlib figure in a window/pane at the visdom server Args: plt: The matplotlib figure/plot to be displayed name: The name of the image window title: The title of the image window caption: The of the image, displayed in the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ if opts is None: opts = {} vis_task = { "type": "matplot_plt", "plt": plt, "name": name, "title": title, "caption": caption, "env_appendix": env_appendix, "opts": opts } self._queue.put_nowait(vis_task) def __show_matplot_plt(self, plt, name=None, title=None, caption=None, env_appendix="", opts=None, **kwargs): """ Internal show_plt_figure method, called by the internal process. This function does all the magic. """ if opts is None: opts = {} opts = opts.copy() opts.update(dict(title=title, caption=caption)) win = self.vis.matplot(plot=plt, win=name, env=self.name + env_appendix, opts=opts) return win @convert_params def show_plotly_plt(self, figure, name=None, env_appendix="", **kwargs): """ Displays an plotly figure in a window/pane at the visdom server Args: figure: The plotly figure/plot to be displayed name: The name of the image window title: The title of the image window caption: The of the image, displayed in the window env_appendix: appendix to the environment name, if used the new env is env+env_appendix opts: opts dict for the ploty/ visdom plot, i.e. can set window size, en/disable ticks,... """ vis_task = { "type": "plotly_plt", "figure": figure, "name": name, "env_appendix": env_appendix, } self._queue.put_nowait(vis_task) def __show_plotly_plt(self, figure, name=None, env_appendix="", **kwargs): """ Internal show_plt_figure method, called by the internal process. This function does all the magic. """ win = self.vis.plotlyplot( figure=figure, win=name, env=self.name + env_appendix, ) return win @convert_params def send_data(self, data, name=None, layout=None, endpoint='events', append=False, **kwargs): """ Sends data to a visdom server. Args: data: The data to be send (has to be in the plotly / visdom format, see the offical visdom github page) name: The name of the window layout: Layout of the data endpoint: Endpoint to recieve the data (or at least to which visdom endpoint to send it to) append: Flag, if data should be appended """ if layout is None: layout = {} vis_task = { "type": "data", "data": data, "layout": layout, "name": name, "endpoint": endpoint, "append": append } self._queue.put_nowait(vis_task) def __send_data(self, data, name=None, layout=None, endpoint='events', append=False, **kwargs): """ Internal show_lineplot method, called by the internal process. This function does all the magic. """ if layout is None: layout = {} if not isinstance(data, (list, type)): data = [data] win = self.vis._send( { 'data': data, 'layout': layout, 'win': name, 'append': append }, endpoint=endpoint) return win def close_all(self): """Closes all visdom windows.""" self.vis.close() def save_vis(self): self.vis.save([self.name]) def exit(self): """Kills the internal process.""" if self._process is not None: self._process.terminate() show_funcs = { "image": __show_image, "images": __show_images, "value": __show_value, "text": __show_text, "progress": __show_progress, "histogram": __show_histogram, "histogram_3d": __show_histogram_3d, "barplot": __show_barplot, "boxplot": __show_boxplot, "surfaceplot": __show_surfaceplot, "contourplot": __show_contourplot, "lineplot": __show_lineplot, "scatterplot": __show_scatterplot, "piechart": __show_piechart, "svg": __show_svg, "add": __add_to_graph, "data": __send_data, "matplot_plt": __show_matplot_plt, "plotly_plt": __show_plotly_plt, }
def run(self): context = TaskContext(self.locks, self.console, self.config, self.setTaskState, self.shutdownEvent, self.driverManager) while not self.shutdownEvent.is_set(): try: self.setState(Worker.IDLE, 'Looking for Task...') with self.locks['tasks']: task = self.tasks.get(block=True, timeout=0.05) taskId = task['id'] self.console.log( 'Worker #%d start process task #%d...' % (self.id, taskId), True, True) try: sleep(0.5) self.setState(Worker.WORKING, 'Prepare Task #%d' % taskId) self.console.log('Running task #%d' % taskId) if 'timeout' in task: timeout = task['timeout'] else: timeout = 180 runner = task['runner'] arguments = task['arguments'] p = Thread(target=runner, args=(taskId, context), kwargs=(arguments)) startTime = time.time() try: p.start() startTime = time.time() self.setState(Worker.WORKING, 'Start task #%d' % taskId) while True: sleep(1) if self.shutdownEvent.is_set(): self.console.notice('Worker #%d shutdown...' % (self.id)) try: p.terminate() except: pass break if p.is_alive() == False: try: p.close() except: pass self.console.success( 'Worker #%d Task #%d succeded.' % (self.id, taskId)) break if (time.time() - startTime) > timeout: self.timeoutCount += 1 self.console.notice( 'Worker #%d Task #%d timeout...' % (self.id, taskId)) try: p.terminate() except: pass break except: self.errorCount += 1 self.console.warning( 'Worker #%d Task #%d error: %s' % (self.id, taskId, traceback.format_exc())) self.taskCount += 1 self.taskDuration += time.time() - startTime self.updateStats() self.console.log('Task #%d Finished' % task['id']) except: self.setState(Worker.ERROR, 'Exception while running task #%d' % taskId) self.console.notice('Worker #%d exception: %s' % (self.id, traceback.format_exc())) except queue.Empty: self.setState(Worker.RUNNING, 'No more tasks, terminate') break except: self.console.warning('Worker #%d Error:' % self.id, sys.exc_info()) break #self.tasks.task_done() self.console.log('Worker #%d finish. Tasks processed : %d' % (self.id, self.stats[self.id]['taskCount'])) self.setState(Worker.STOPPED, 'Terminated') return True
class Manager(object): """Manager This is the base Manager of the BaseComponent which manages an Event Queue, a set of Event Handlers, Channels, Tick Functions, Registered and Hidden Components, a Task and the Running State. @ivar manager: The Manager of this Component or Manager """ def __init__(self, *args, **kwargs): "initializes x; see x.__class__.__doc__ for signature" self._queue = deque() self._handlers = set() self._globals = [] self.channels = dict() self._cmap = dict() self._tmap = dict() self._ticks = set() self.components = set() self._task = None self._running = False self.root = self self.manager = self def __repr__(self): "x.__repr__() <==> repr(x)" name = self.__class__.__name__ q = len(self._queue) c = len(self.channels) h = len(self._handlers) state = self.state format = "<%s (q: %d c: %d h: %d) [%s]>" return format % (name, q, c, h, state) def __len__(self): """x.__len__() <==> len(x) Returns the number of events in the Event Queue. """ return len(self._queue) def __add__(self, y): """x.__add__(y) <==> x+y (Optional) Convenience operator to register y with x Equivalent to: y.register(x) @return: x @rtype Component or Manager """ y.register(self) return self def __iadd__(self, y): """x.__iadd__(y) <==> x += y (Optional) Convenience operator to register y with x Equivalent to: y.register(x) @return: x @rtype Component or Manager """ y.register(self) return self def __sub__(self, y): """x.__sub__(y) <==> x-y (Optional) Convenience operator to unregister y from x.manager Equivalent to: y.unregister() @return: x @rtype Component or Manager """ if y.manager == self: y.unregister() return self else: raise TypeError("No registration found for %r" % y) def __isub__(self, y): """x.__sub__(y) <==> x -= y (Optional) Convenience operator to unregister y from x Equivalent to: y.unregister() @return: x @rtype Component or Manager """ if y.manager == self: y.unregister() return self else: raise TypeError("No registration found for %r" % y) def _getHandlers(self, _channel): target, channel = _channel channels = self.channels exists = self.channels.has_key get = self.channels.get tmap = self._tmap.get cmap = self._cmap.get # Global Channels handlers = self._globals # This channel on all targets if channel == "*": all = tmap(target, []) return chain(handlers, all) # Every channel on this target if target == "*": all = cmap(channel, []) return chain(handlers, all) # Any global channels if exists(("*", channel)): handlers = chain(handlers, get(("*", channel))) # Any global channels for this target if exists((channel, "*")): handlers = chain(handlers, get((channel, "*"))) # The actual channel and target if exists(_channel): handlers = chain(handlers, get((_channel))) return handlers @property def name(self): return self.__class__.__name__ @property def running(self): return self._running @property def state(self): if self.running: if self._task is None: return "R" else: if self._task.isAlive(): return "R" else: return "D" else: return "S" def _add(self, handler, channel=None): """E._add(handler, channel) -> None Add a new Event Handler to the Event Manager adding it to the given channel. If no channel is given, add it to the global channel. """ if channel is None: if handler not in self._globals: self._globals.append(handler) self._globals.sort(key=_sortkey) self._globals.reverse() else: assert type(channel) is tuple and len(channel) == 2 self._handlers.add(handler) if channel not in self.channels: self.channels[channel] = [] if handler not in self.channels[channel]: self.channels[channel].append(handler) self.channels[channel].sort(key=_sortkey) self.channels[channel].reverse() (target, channel) = channel if target not in self._tmap: self._tmap[target] = [] if handler not in self._tmap[target]: self._tmap[target].append(handler) if channel not in self._cmap: self._cmap[channel] = [] if handler not in self._cmap[channel]: self._cmap[channel].append(handler) def _remove(self, handler, channel=None): """E._remove(handler, channel=None) -> None Remove the given Event Handler from the Event Manager removing it from the given channel. if channel is None, remove it from all channels. This will succeed even if the specified handler has already been removed. """ if channel is None: if handler in self._globals: self._globals.remove(handler) channels = self.channels.keys() else: channels = [channel] if handler in self._handlers: self._handlers.remove(handler) for channel in channels: if handler in self.channels[channel]: self.channels[channel].remove(handler) if not self.channels[channel]: del self.channels[channel] (target, channel) = channel if target in self._tmap and handler in self._tmap: self._tmap[target].remove(handler) if not self._tmap[target]: del self._tmap[target] if channel in self._cmap and handler in self._cmap: self._cmap[channel].remove(handler) if not self._cmap[channel]: del self._cmap[channel] def _push(self, event, channel): self._queue.append((event, channel)) def push(self, event, channel=None, target=None): """Push a new Event into the queue This will push the given Event, Channel and Target onto the Event Queue for later processing. if target is None, then target will be set as the Channel of the current Component, self.channel (defaulting back to None). If this Component's Manager is itself, enqueue on this Component's Event Queue, otherwise enqueue on this Component's Manager. @param event: The Event Object @type event: Event @param channel: The Channel this Event is bound for @type channel: str @keyword target: The target Component's channel this Event is bound for @type target: str or Component """ channel = channel or event.channel or event.name.lower() target = target if target is not None else event.target if isinstance(target, Component): target = getattr(target, "channel", "*") else: target = target or getattr(self, "channel", "*") event.channel = (target, channel) self.root._push(event, (target, channel)) def _flush(self): q = self._queue self._queue = deque() while q: self._send(*q.popleft()) def flush(self): """Flush all Events in the Event Queue This will flush all Events in the Event Queue. If this Component's Manager is itself, flush all Events from this Component's Event Queue, otherwise, flush all Events from this Component's Manager's Event Queue. """ self.root._flush() def _send(self, event, channel, errors=False, log=True): eargs = event.args ekwargs = event.kwargs r = False for handler in self._getHandlers(channel): try: #stime = time.time() if handler._passEvent: r = handler(event, *eargs, **ekwargs) else: r = handler(*eargs, **ekwargs) #etime = time.time() #ttime = (etime - stime) * 1e3 #print "%s: %0.02f ms" % (reprhandler(handler), ttime) except (KeyboardInterrupt, SystemExit): raise except: if log: etype, evalue, etraceback = _exc_info() self.push(Error(etype, evalue, etraceback, handler=handler)) if errors: raise else: _exc_clear() if r is not None and r and handler.filter: return r return r def send(self, event, channel=None, target=None, errors=False, log=True): """Send a new Event to Event Handlers for the Target and Channel This will send the given Event, to the spcified CHannel on the Target Component's Channel. if target is None, then target will be set as the Channel of the current Component, self.channel (defaulting back to None). If this Component's Manager is itself, enqueue on this Component's Event Queue, otherwise enqueue on this Component's Manager. @param event: The Event Object @type event: Event @param channel: The Channel this Event is bound for @type channel: str @keyword target: The target Component's channel this Event is bound for @type target: str or Component @keyword errors: True to raise errors, False otherwise @type errors: bool @keyword log: True to log errors, False otherwise @type log: bool @return: The return value of the last executed Event Handler @rtype: object """ channel = channel or event.channel or event.name.lower() target = target if target is not None else event.target if isinstance(target, Component): target = getattr(target, "channel", "*") else: target = target or getattr(self, "channel", "*") event.channel = (target, channel) return self.root._send(event, (target, channel), errors, log) def _signal(self, signal, stack): if not self.send(Signal(signal, stack), "signal"): if signal == SIGINT: raise KeyboardInterrupt elif signal == SIGTERM: raise SystemExit def start(self, sleep=0, log=True, process=False): group = None target = self.run name = self.__class__.__name__ mode = "P" if process else "T" args = (sleep, mode, log,) if process and HAS_MULTIPROCESSING: args += (self,) self._task = Process(group, target, name, args) setattr(self._task, "isAlive", self._task.is_alive) self._task.start() return self._task = Thread(group, target, name, args) self._task.setDaemon(True) self._task.start() def join(self, timeout=None): if hasattr(self._task, "join"): self._task.join(timeout) def stop(self): self._running = False if hasattr(self._task, "terminate"): self._task.terminate() if hasattr(self._task, "join"): self._task.join(3) self._task = None def _terminate(self): if HAS_MULTIPROCESSING: for p in processes(): if not p == process(): p.terminate() p.join(3) def run(self, sleep=0, mode=None, log=True, __self=None): if __self is not None: self = __self if not mode == "T": if os.name == "posix": signal(SIGHUP, self._signal) signal(SIGINT, self._signal) signal(SIGTERM, self._signal) self._running = True self.push(Started(self, mode)) try: while self.running: try: [f() for f in self._ticks.copy()] self._flush() if sleep: try: time.sleep(sleep) except: pass except (KeyboardInterrupt, SystemExit): self._running = False except: try: if log: self.push(Error(*_exc_info())) finally: self._flush() finally: try: self.push(Stopped(self)) rtime = time.time() while len(self) > 0 and (time.time() - rtime) < 3: try: [f() for f in self._ticks.copy()] self._flush() if sleep: time.sleep(sleep) rtime = time.time() except: try: if log: self.push(Error(*_exc_info())) finally: self._flush() except: pass
class RGBDStreamer: """ This class is capable of browsing through an RGB-D data stream (videos, devices) while calibrating the data """ pclStreamer = RGBDCalibration() # Creates a single static copy of the PCL based streamer object def __init__(self, frame_callback=None, connection_callback=None, calibrate=True, state_function=None, blocking=True): """ Starts the RGBD streamer object The parameters are the following: - frame_callback: a callback function this object will call whenever a new calibrated RGBD frame is available - connection_callback: this is called whenever there is an update in the connection. - calibrate: Whether to calibrate the RGB-D data or not. If not, then the only thing it's retrieved are the RGB and Depth frames. - stateFunction: This is a function which this module calls as soon as a new RGB-D frame is read. It is useful to capture external information with timing as close as possible to the timing a frame is read """ # Configuring the behavior self.frame_callback = frame_callback self.connection_callback = connection_callback self.calibrate = calibrate self.state_function = state_function self.blocking = blocking # Blocking behavior for the caller application # Inner states self.streamLoopRunning = True self.paused = False self.delta = False # The source object for recorded RGB-D data. Devices data sources are handled inside pclStreamer self.recordedSource = None # The object with the relevant calibration data self.KDH = RGBDCamera() # By providing the references to the PCLStreamer of the cameras, it should be enough to do the calibration self.pclStreamer.setCameras(self.KDH.rgb_camera, self.KDH.depth_camera) self.connected = False self.N_frames = 100 # The fifo of frames self.FIFO = deque() self.frameLock = Lock() self.recordingsLock = Lock() self.frameIndex = -1 # Inner thread which is retrieving calibrated frames self.streamThread = Thread(target=self.streamLoop) self.streamThread.start() # Inner thread which is reading recorded RGB-D data (e.g. video files). Emulates a behavior like OpenNI but, # due to python restrictions, it would still run in the same CPU as the main thread self.RGBDReadThread = Thread(target=self.readRecordedLoop) self.RGBDReadThread.start() def kill(self): self.disconnect() self.streamLoopRunning = False# This should eventually kill the listening thread if self.streamThread.is_alive(): self.streamThread.join(0.5) if self.streamThread.is_alive(): self.streamThread.terminate() if self.RGBDReadThread.is_alive(): self.RGBDReadThread.join(0.5) if self.RGBDReadThread.is_alive(): self.RGBDReadThread.terminate() def __del__(self): self.kill() def setStateFunction(self, state_function=None): self.state_function = state_function def toggleConnect(self, devFile=0, calFile=None): if self.connected: self.disconnect() else: self.connect(devFile, calFile) def connect(self, source_description=0, calFile=None): """ According to source_description this will establish a connection to the specified source of RGBD data The options of sources of data are the diverse. An integer refers to a the connected camera with that same index. A string normally refers to the path to recorded data. According to the extension we'll decide on the source object which will be created to manage it. We can also specify a calibration file. Even though OpenNI is handling some calibration (registration between depth and rgb), we still have the option to override that by specifying the calibration file to be used. """ if self.connected: self.disconnect() self.pause(True) self.pclStreamer.setCalibration(self.calibrate) if source_description.__class__ is int: # If we are connecting to a device if config.CONNECTED_DEVICE_SUPPORT: self.pclStreamer.connectDevice(source_description) if self.calibrate: if calFile is not None: self.KDH.setCalibration(calFile) else: if config.PCL_FOUND: self.KDH.setOpenNIParameters(self.pclStreamer) pass self.recordedSource = None else: return else: self.recordedSource = RGBD_VideoSource(source_description) self.N_frames = self.recordedSource.N_frames if self.calibrate: if calFile is None: self.KDH.setCalibration(None) else: print '<<<<<<<<< LOADING PARAMETERS FILE ', calFile, ">>>>>>>>>>>>>>>>" self.KDH.setCalibration(calFile) self.connected = True if self.connection_callback is not None: self.connection_callback(self.connected) def disconnect(self): """ This function kills the data source object """ if self.recordedSource is not None: self.recordedSource.close() self.recordedSource = None else: self.pclStreamer.disconnectDevice() self.connected = False if self.connection_callback is not None: self.connection_callback(self.connected) def isConnected(self): return self.connected def jump(self, frameIndex): """ Jump to the indicated frame index. It is not relevant for a connected device """ if self.recordedSource is not None: self.recordingsLock.acquire() self.delta = True # To capture the next frame self.recordedSource.jump(frameIndex) self.recordingsLock.release() def pause(self, p=True): self.paused = p self.pclStreamer.setPause(p) def next(self): """ When connected and paused, this function allows to retrieve the next frame without unpausing """ if self.connected and self.paused: self.delta=True def popFrame(self): theFrame = None self.frameLock.acquire()# newFrame is used also in another thread if len(self.FIFO)>0: theFrame = self.FIFO.pop()# Take the newest frame self.FIFO.clear()# Not to have an explosion of memory self.frame_callback_called = False self.frameLock.release() return theFrame def streamLoop(self): """ Infinite loop which is retrieving frames when needed. Calling the broadcast function when a frame is available to the user of this class. """ prev_time = time.time() read_count = 0 anRGBDFrame = RGBDContainer() self.frame_callback_called = False while self.streamLoopRunning: if self.connected and not self.frame_callback_called: frameSuccess = self.pclStreamer.getFrameData(anRGBDFrame) if frameSuccess: # The frame was well taken state = None if self.state_function is not None: state = self.state_function() # Gets the state of the caller app ASAP, before further processing or waiting for response state = state, time.time() if self.calibrate: dM = DepthMesh(anRGBDFrame, self.KDH) newFrame = (dM.texture, dM.depth, dM.vcs, dM.txcoord, dM , state), anRGBDFrame.frameIndex else: rgb, depth, vcs, norms, valid_points = anRGBDFrame.getCloudArrays() newFrame = (rgb , depth , None , None , anRGBDFrame, state), anRGBDFrame.frameIndex self.frameLock.acquire() self.FIFO.clear() self.FIFO.append(newFrame) self.frameIndex = 0 if self.frame_callback is not None: self.frame_callback() self.frame_callback_called = self.blocking self.frameLock.release() anRGBDFrame = RGBDContainer() read_count+=1 time.sleep(0.001) if time.time()-prev_time > 1.0: if not self.paused: print ' >>>>>> Working at ',read_count,' fps <<<<<' read_count, prev_time = 0, time.time() else: time.sleep(0.001) def readRecordedLoop(self): """ Infinite loop retrieving recorded frames and dumping them into the RGBD Calibration The reason this was designed in this way is that the main logic for calibration and data streaming will be independent of whether the data stream comes from video files or from a device. Therefore the loop in streamLoopRunning does not care about this, besides, the actual calibration can be handled in a different thread in the C++ side, which allows to allocate the calibration logic in another CPU than the main thread. """ while self.streamLoopRunning: if self.recordedSource is not None and (not self.paused or self.delta) and self.pclStreamer.RGBDFrameProcessed(): self.delta = False self.recordingsLock.acquire() # To protect the flow of data when there are jumps depth, rgb, frameIndex = self.recordedSource.getData() if depth is not None and rgb is not None: self.pclStreamer.processPyRGBD(depth, rgb, frameIndex) else: self.disconnect() # We have reached the end of the file, or it tried to do something unusual self.recordingsLock.release() time.sleep(0.001)
class RGBDStreamer: """ This class is capable of browsing through an RGB-D data stream (videos, devices) while calibrating the data """ pclStreamer = RGBDCalibration( ) # Creates a single static copy of the PCL based streamer object def __init__(self, frame_callback=None, connection_callback=None, calibrate=True, state_function=None, blocking=True): """ Starts the RGBD streamer object The parameters are the following: - frame_callback: a callback function this object will call whenever a new calibrated RGBD frame is available - connection_callback: this is called whenever there is an update in the connection. - calibrate: Whether to calibrate the RGB-D data or not. If not, then the only thing it's retrieved are the RGB and Depth frames. - stateFunction: This is a function which this module calls as soon as a new RGB-D frame is read. It is useful to capture external information with timing as close as possible to the timing a frame is read """ # Configuring the behavior self.frame_callback = frame_callback self.connection_callback = connection_callback self.calibrate = calibrate self.state_function = state_function self.blocking = blocking # Blocking behavior for the caller application # Inner states self.streamLoopRunning = True self.paused = False self.delta = False # The source object for recorded RGB-D data. Devices data sources are handled inside pclStreamer self.recordedSource = None # The object with the relevant calibration data self.KDH = RGBDCamera() # By providing the references to the PCLStreamer of the cameras, it should be enough to do the calibration self.pclStreamer.setCameras(self.KDH.rgb_camera, self.KDH.depth_camera) self.connected = False self.N_frames = 100 # The fifo of frames self.FIFO = deque() self.frameLock = Lock() self.recordingsLock = Lock() self.frameIndex = -1 # Inner thread which is retrieving calibrated frames self.streamThread = Thread(target=self.streamLoop) self.streamThread.start() # Inner thread which is reading recorded RGB-D data (e.g. video files). Emulates a behavior like OpenNI but, # due to python restrictions, it would still run in the same CPU as the main thread self.RGBDReadThread = Thread(target=self.readRecordedLoop) self.RGBDReadThread.start() def kill(self): self.disconnect() self.streamLoopRunning = False # This should eventually kill the listening thread if self.streamThread.is_alive(): self.streamThread.join(0.5) if self.streamThread.is_alive(): self.streamThread.terminate() if self.RGBDReadThread.is_alive(): self.RGBDReadThread.join(0.5) if self.RGBDReadThread.is_alive(): self.RGBDReadThread.terminate() def __del__(self): self.kill() def setStateFunction(self, state_function=None): self.state_function = state_function def toggleConnect(self, devFile=0, calFile=None): if self.connected: self.disconnect() else: self.connect(devFile, calFile) def connect(self, source_description=0, calFile=None): """ According to source_description this will establish a connection to the specified source of RGBD data The options of sources of data are the diverse. An integer refers to a the connected camera with that same index. A string normally refers to the path to recorded data. According to the extension we'll decide on the source object which will be created to manage it. We can also specify a calibration file. Even though OpenNI is handling some calibration (registration between depth and rgb), we still have the option to override that by specifying the calibration file to be used. """ if self.connected: self.disconnect() self.pause(True) self.pclStreamer.setCalibration(self.calibrate) if source_description.__class__ is int: # If we are connecting to a device if config.CONNECTED_DEVICE_SUPPORT: self.pclStreamer.connectDevice(source_description) if self.calibrate: if calFile is not None: self.KDH.setCalibration(calFile) else: if config.PCL_FOUND: self.KDH.setOpenNIParameters(self.pclStreamer) pass self.recordedSource = None else: return else: self.recordedSource = RGBD_VideoSource(source_description) self.N_frames = self.recordedSource.N_frames if self.calibrate: if calFile is None: self.KDH.setCalibration(None) else: print '<<<<<<<<< LOADING PARAMETERS FILE ', calFile, ">>>>>>>>>>>>>>>>" self.KDH.setCalibration(calFile) self.connected = True if self.connection_callback is not None: self.connection_callback(self.connected) def disconnect(self): """ This function kills the data source object """ if self.recordedSource is not None: self.recordedSource.close() self.recordedSource = None else: self.pclStreamer.disconnectDevice() self.connected = False if self.connection_callback is not None: self.connection_callback(self.connected) def isConnected(self): return self.connected def jump(self, frameIndex): """ Jump to the indicated frame index. It is not relevant for a connected device """ if self.recordedSource is not None: self.recordingsLock.acquire() self.delta = True # To capture the next frame self.recordedSource.jump(frameIndex) self.recordingsLock.release() def pause(self, p=True): self.paused = p self.pclStreamer.setPause(p) def next(self): """ When connected and paused, this function allows to retrieve the next frame without unpausing """ if self.connected and self.paused: self.delta = True def popFrame(self): theFrame = None self.frameLock.acquire() # newFrame is used also in another thread if len(self.FIFO) > 0: theFrame = self.FIFO.pop() # Take the newest frame self.FIFO.clear() # Not to have an explosion of memory self.frame_callback_called = False self.frameLock.release() return theFrame def streamLoop(self): """ Infinite loop which is retrieving frames when needed. Calling the broadcast function when a frame is available to the user of this class. """ prev_time = time.time() read_count = 0 anRGBDFrame = RGBDContainer() self.frame_callback_called = False while self.streamLoopRunning: if self.connected and not self.frame_callback_called: frameSuccess = self.pclStreamer.getFrameData(anRGBDFrame) if frameSuccess: # The frame was well taken state = None if self.state_function is not None: state = self.state_function( ) # Gets the state of the caller app ASAP, before further processing or waiting for response state = state, time.time() if self.calibrate: dM = DepthMesh(anRGBDFrame, self.KDH) newFrame = (dM.texture, dM.depth, dM.vcs, dM.txcoord, dM, state), anRGBDFrame.frameIndex else: rgb, depth, vcs, norms, valid_points = anRGBDFrame.getCloudArrays( ) newFrame = (rgb, depth, None, None, anRGBDFrame, state), anRGBDFrame.frameIndex self.frameLock.acquire() self.FIFO.clear() self.FIFO.append(newFrame) self.frameIndex = 0 if self.frame_callback is not None: self.frame_callback() self.frame_callback_called = self.blocking self.frameLock.release() anRGBDFrame = RGBDContainer() read_count += 1 time.sleep(0.001) if time.time() - prev_time > 1.0: if not self.paused: print ' >>>>>> Working at ', read_count, ' fps <<<<<' read_count, prev_time = 0, time.time() else: time.sleep(0.001) def readRecordedLoop(self): """ Infinite loop retrieving recorded frames and dumping them into the RGBD Calibration The reason this was designed in this way is that the main logic for calibration and data streaming will be independent of whether the data stream comes from video files or from a device. Therefore the loop in streamLoopRunning does not care about this, besides, the actual calibration can be handled in a different thread in the C++ side, which allows to allocate the calibration logic in another CPU than the main thread. """ while self.streamLoopRunning: if self.recordedSource is not None and ( not self.paused or self.delta) and self.pclStreamer.RGBDFrameProcessed(): self.delta = False self.recordingsLock.acquire( ) # To protect the flow of data when there are jumps depth, rgb, frameIndex = self.recordedSource.getData() if depth is not None and rgb is not None: self.pclStreamer.processPyRGBD(depth, rgb, frameIndex) else: self.disconnect( ) # We have reached the end of the file, or it tried to do something unusual self.recordingsLock.release() time.sleep(0.001)
class Manager(object): """Manager This is the base Manager of the BaseComponent which manages an Event Queue, a set of Event Handlers, Channels, Tick Functions, Registered and Hidden Components, a Task and the Running State. @ivar manager: The Manager of this Component or Manager """ def __init__(self, *args, **kwargs): "initializes x; see x.__class__.__doc__ for signature" self._queue = deque() self._handlers = set() self._channels = defaultdict(list) self._ticks = set() self._components = set() self._task = None self._running = False self.manager = self def __repr__(self): "x.__repr__() <==> repr(x)" name = self.__class__.__name__ q = len(self._queue) c = len(self._channels) h = len(self._handlers) state = self.state format = "<%s (q: %d c: %d h: %d) [%s]>" return format % (name, q, c, h, state) def __len__(self): """x.__len__() <==> len(x) Returns the number of events in the Event Queue. """ return len(self._queue) def __add__(self, y): """x.__add__(y) <==> x+y (Optional) Convenience operator to register y with x Equivalent to: y.register(x) @return: x @rtype Component or Manager """ y.register(self) return self def __iadd__(self, y): """x.__iadd__(y) <==> x += y (Optional) Convenience operator to register y with x Equivalent to: y.register(x) @return: x @rtype Component or Manager """ y.register(self) return self def __sub__(self, y): """x.__sub__(y) <==> x-y (Optional) Convenience operator to unregister y from x.manager Equivalent to: y.unregister() @return: x @rtype Component or Manager """ if y.manager == self: y.unregister() return self else: raise TypeError("No registration found for %r" % y) def __isub__(self, y): """x.__sub__(y) <==> x -= y (Optional) Convenience operator to unregister y from x Equivalent to: y.unregister() @return: x @rtype Component or Manager """ if y.manager == self: y.unregister() return self else: raise TypeError("No registration found for %r" % y) def _getHandlers(self, s): if s == "*:*": return self._handlers if ":" in s: target, channel = s.split(":", 1) else: channel = s target = None channels = self.channels globals = channels["*"] if target == "*": c = ":%s" % channel x = [channels[k] for k in channels if k == channel or k.endswith(c)] all = [i for y in x for i in y] return chain(globals, all) if channel == "*": c = "%s:" % target x = [channels[k] for k in channels if k.startswith(c) or ":" not in k] all = [i for y in x for i in y] return chain(globals, all) handlers = globals if channel in channels: handlers = chain(handlers, channels[channel]) if target and "%s:*" % target in channels: handlers = chain(handlers, channels["%s:*" % target]) if "*:%s" % channel in channels: handlers = chain(handlers, channels["*:%s" % channel]) if target: handlers = chain(handlers, channels[s]) return handlers @property def state(self): if self._running: if self._task is None: return "R" else: if self._task.is_alive(): return "R" else: return "D" else: return "S" @property def running(self): return self._running @property def components(self): return self._components @property def channels(self): return self._channels @property def ticks(self): return self._ticks def _add(self, handler, channel=None): """E._add(handler, channel) -> None Add a new Event Handler to the Event Manager adding it to the given channel. If no channel is given, add it to the global channel. """ self._handlers.add(handler) if channel is None: channel = "*" if channel in self.channels: if handler not in self.channels[channel]: self._channels[channel].append(handler) self._channels[channel].sort( key=attrgetter("priority", "filter")) self._channels[channel].reverse() else: self._channels[channel] = [handler] def _remove(self, handler, channel=None): """E._remove(handler, channel=None) -> None Remove the given Event Handler from the Event Manager removing it from the given channel. if channel is None, remove it from all channels. This will succeed even if the specified handler has already been removed. """ if channel is None: channels = self.channels.keys() else: channels = [channel] if handler in self._handlers: self._handlers.remove(handler) for channel in channels: if handler in self.channels[channel]: self._channels[channel].remove(handler) if not self._channels[channel]: del self._channels[channel] def push(self, event, channel, target=None): """Push a new Event into the queue This will push the given Event, Channel and Target onto the Event Queue for later processing. if target is None, then target will be set as the Channel of the current Component, self.channel (defaulting back to None). If this Component's Manager is itself, enqueue on this Component's Event Queue, otherwise enqueue on this Component's Manager. @param event: The Event Object @type event: Event @param channel: The Channel this Event is bound for @type channel: str @keyword target: The target Component's channel this Event is bound for @type target: str or Component """ if target is None: target = getattr(self, "channel", None) if self.manager == self: self._queue.append((event, channel, target)) else: self.manager.push(event, channel, target) def flush(self): """Flush all Events in the Event Queue This will flush all Events in the Event Queue. If this Component's Manager is itself, flush all Events from this Component's Event Queue, otherwise, flush all Events from this Component's Manager's Event Queue. """ if self.manager == self: q = self._queue self._queue = deque() while q: event, channel, target = q.popleft() self.send(event, channel, target) else: self.manager.flush() def send(self, event, channel, target=None, errors=False, log=True): """Send a new Event to Event Handlers for the Target and Channel This will send the given Event, to the spcified CHannel on the Target Component's Channel. if target is None, then target will be set as the Channel of the current Component, self.channel (defaulting back to None). If this Component's Manager is itself, enqueue on this Component's Event Queue, otherwise enqueue on this Component's Manager. @param event: The Event Object @type event: Event @param channel: The Channel this Event is bound for @type channel: str @keyword target: The target Component's channel this Event is bound for @type target: str or Component @keyword errors: True to raise errors, False otherwise @type errors: bool @keyword log: True to log errors, False otherwise @type log: bool @return: The return value of the last executed Event Handler @rtype: object """ if target is None: target = getattr(self, "channel", None) if self.manager == self: event.channel = channel event.target = target eargs = event.args ekwargs = event.kwargs if target is not None and isinstance(target, Component): target = getattr(target, "channel", None) if target is not None and type(target) == str: channel = "%s:%s" % (target, channel) r = False for handler in self._getHandlers(channel): try: if handler._passEvent: r = partial(handler, event, *eargs, **ekwargs)() else: r = partial(handler, *eargs, **ekwargs)() except (KeyboardInterrupt, SystemExit): raise except: if log: self.push(Error(*_exc_info()), "error") if errors: raise else: _exc_clear() if r is not None and r and handler.filter: return r return r else: return self.manager.send(event, channel, target, errors, log) def _signal(self, signal, stack): if not self.send(Signal(signal, stack), "signal"): if signal == SIGINT: raise KeyboardInterrupt elif signal == SIGTERM: raise SystemExit def start(self, sleep=0, errors=True, log=True, process=False): group = None target = self.run name = self.__class__.__name__ mode = "P" if process else "T" args = (sleep, mode, errors, log,) if process and HAS_MULTIPROCESSING: args += (self,) self._task = Process(group, target, name, args) if HAS_MULTIPROCESSING == 1: setattr(self._task, "is_alive", self._task.isAlive) self._task.start() return self._task = Thread(group, target, name, args) self._task.setDaemon(True) self._task.start() def stop(self): self._running = False if hasattr(self._task, "terminate"): self._task.terminate() if hasattr(self._task, "join"): self._task.join(3) self._task = None def _terminate(self): if HAS_MULTIPROCESSING: for p in processes(): if not p == process(): p.terminate() p.join(3) def run(self, sleep=0, mode=None, errors=False, log=True, __self=None): if __self is not None: self = __self if not mode == "T": #signal(SIGHUP, self._signal) signal(SIGINT, self._signal) signal(SIGTERM, self._signal) self._running = True self.push(Started(self, mode), "started") try: while self._running: try: [f() for f in self.ticks.copy()] self.flush() if sleep: try: time.sleep(sleep) except: pass except (KeyboardInterrupt, SystemExit): self._running = False except: try: if log: self.push(Error(*_exc_info()), "error") if errors: raise else: _exc_clear() except: pass finally: try: self.push(Stopped(self), "stopped") rtime = time.time() while len(self) > 0 and (time.time() - rtime) < 3: [f() for f in self.ticks.copy()] self.flush() if sleep: time.sleep(sleep) rtime = time.time() except: pass
shot=Queue.Queue() ud=Queue.Queue() mode=modesel() convert= Thread(target=textdet, args=(shot,q,mode)) convert.start() if mode==1: speak= Thread(target=speakword, args=(q,)) speak.start() read= Thread(target=calculateri, args=(shot,sx,sy,ud)) read.start() aud=Thread(target=audio, args=(ud,)) aud.start() while True: k = cv2.waitKey(5) & 0xFF if k == 27: convert.terminate() speak.terminate() read.terminate() aud.terminate() break cv2.destroyAllWindows()
def function_handler(event): start_time = time.time() log_level = event['log_level'] cloud_logging_config(log_level) logger.debug("Action handler started") extra_env = event.get('extra_env', {}) os.environ.update(extra_env) config = event['config'] call_status = CallStatus(config) call_status.response['host_submit_time'] = event['host_submit_time'] call_status.response['start_time'] = start_time context_dict = { 'python_version': os.environ.get("PYTHON_VERSION"), } call_id = event['call_id'] job_id = event['job_id'] executor_id = event['executor_id'] exec_id = "{}/{}/{}".format(executor_id, job_id, call_id) logger.info("Execution ID: {}".format(exec_id)) execution_timeout = event['execution_timeout'] logger.debug( "Set function execution timeout to {}s".format(execution_timeout)) func_key = event['func_key'] data_key = event['data_key'] data_byte_range = event['data_byte_range'] call_status.response['call_id'] = call_id call_status.response['job_id'] = job_id call_status.response['executor_id'] = executor_id call_status.response['activation_id'] = os.environ.get( '__OW_ACTIVATION_ID') try: if version.__version__ != event['pywren_version']: raise Exception("WRONGVERSION", "PyWren version mismatch", version.__version__, event['pywren_version']) # send init status event call_status.send('__init__') # call_status.response['free_disk_bytes'] = free_disk_space("/tmp") custom_env = { 'PYWREN_CONFIG': json.dumps(config), 'PYWREN_FUNCTION': 'True', 'PYWREN_EXECUTION_ID': exec_id, 'PYWREN_STORAGE_BUCKET': config['pywren']['storage_bucket'], 'PYTHONPATH': "{}:{}".format(os.getcwd(), PYWREN_LIBS_PATH), 'PYTHONUNBUFFERED': 'True' } os.environ.update(custom_env) # if os.path.exists(JOBRUNNER_STATS_BASE_DIR): # shutil.rmtree(JOBRUNNER_STATS_BASE_DIR, True) jobrunner_stats_dir = os.path.join(STORAGE_BASE_DIR, executor_id, job_id, call_id) os.makedirs(jobrunner_stats_dir, exist_ok=True) jobrunner_stats_filename = os.path.join(jobrunner_stats_dir, 'jobrunner.stats.txt') jobrunner_config = { 'pywren_config': config, 'call_id': call_id, 'job_id': job_id, 'executor_id': executor_id, 'func_key': func_key, 'data_key': data_key, 'log_level': log_level, 'data_byte_range': data_byte_range, 'output_key': create_output_key(JOBS_PREFIX, executor_id, job_id, call_id), 'stats_filename': jobrunner_stats_filename } setup_time = time.time() call_status.response['setup_time'] = round(setup_time - start_time, 8) handler_conn, jobrunner_conn = Pipe() jobrunner = JobRunner(jobrunner_config, jobrunner_conn) logger.debug('Starting JobRunner process') local_execution = strtobool(os.environ.get('LOCAL_EXECUTION', 'False')) if local_execution: jrp = Thread(target=jobrunner.run) else: jrp = Process(target=jobrunner.run) jrp.daemon = True jrp.start() jrp.join(execution_timeout) logger.debug('JobRunner process finished') call_status.response['exec_time'] = round(time.time() - setup_time, 8) if jrp.is_alive(): # If process is still alive after jr.join(job_max_runtime), kill it try: jrp.terminate() except Exception: # thread does not have terminate method pass msg = ('Jobrunner process exceeded maximum time of {} ' 'seconds and was killed'.format(execution_timeout)) raise Exception('OUTATIME', msg) try: handler_conn.recv() except EOFError: logger.error( 'No completion message received from JobRunner process') logger.debug('Assuming memory overflow...') # Only 1 message is returned by jobrunner when it finishes. # If no message, this means that the jobrunner process was killed. # 99% of times the jobrunner is killed due an OOM, so we assume here an OOM. msg = 'Jobrunner process exceeded maximum memory and was killed' raise Exception('OUTOFMEMORY', msg) # print(subprocess.check_output("find {}".format(PYTHON_MODULE_PATH), shell=True)) # print(subprocess.check_output("find {}".format(os.getcwd()), shell=True)) if os.path.exists(jobrunner_stats_filename): with open(jobrunner_stats_filename, 'r') as fid: for l in fid.readlines(): key, value = l.strip().split(" ", 1) try: call_status.response[key] = float(value) except Exception: call_status.response[key] = value if key in [ 'exception', 'exc_pickle_fail', 'result', 'new_futures' ]: call_status.response[key] = eval(value) # call_status.response['server_info'] = get_server_info() call_status.response.update(context_dict) call_status.response['end_time'] = time.time() except Exception: # internal runtime exceptions print('----------------------- EXCEPTION !-----------------------', flush=True) traceback.print_exc(file=sys.stdout) print('----------------------------------------------------------', flush=True) call_status.response['end_time'] = time.time() call_status.response['exception'] = True pickled_exc = pickle.dumps(sys.exc_info()) pickle.loads( pickled_exc) # this is just to make sure they can be unpickled call_status.response['exc_info'] = str(pickled_exc) finally: call_status.send('__end__') logger.info("Finished")
class Node(): ips = [] def __init__(self, _id): self.id = int(_id) self.ip = Node.ips[self.id] self.lock = Lock() self.listener = SocketServer.TCPServer(('0.0.0.0', 6000), MyTCPHandler) self.listener.node = self self.thread = Thread(target = self.listener.serve_forever) self.thread.start() self.entry_set = calendar.EntrySet() self.init_calendar() self.log = open("log.dat", "a+") self.last = None if os.path.isfile("log.dat"): self.entry_set.create_from_log(self) def init_calendar(self): self.table = TimeTable(len(Node.ips)) self.events = [] def kill(): print('killin') self.listener.shutdown() # Expect data in the form: # {'table': <serialized table>, 'events': <array of events>} def receive(self, raw): data = json.loads(raw) print(self.table.table) print(data) if data['type'] == "failure": self.rec_failure(data) else: new_table = TimeTable.load(json.loads(data['table']), len(Node.ips)) events = data['events'] new_events =[] for event in events: event = Event.load(json.loads(event)) if event.entry: event.entry = Entry.load(event.entry) new_events.append(event) # For all events this node doesn't have, make modifications for event in new_events: if not self.has_event(event, self.id): res = event.apply(self.entry_set, self) if res: self.events.append(event) else: if event.type == MessageTypes.Insert: self.send_failure(event) self.table.sync(new_table, self.id, data['node_id']) print(self.table.table) def send(self, _id, event=None): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: data = "data" # print("Sending Data from client") # Connect to server and send data sock.settimeout(3) sock.connect((Node.ips[_id], 6000)) sock.sendall(event) # Receive data from the server and shut down received = sock.recv(1024) # Add To EntrySet except: # Node Down cancel conflict if not event == None: print("Failed to connect to node: " + str(_id)) d = json.loads(event) dd = json.loads(d['events'][0]) event = Event.load(dd) event.entry = Entry.load(event.entry) self.delete_entry(event.entry, [_id]) pass finally: sock.close() def send_failure(self, event): #grab id from event print("Sending Failure command") data = { 'node_id': self.id, 'type': 'failure', 'event': event.to_JSON() } self.send(event.node, json.dumps(data)) def rec_failure(self, data): event = Event.load(json.loads(data['event'])) event.entry = Entry.load(event.entry) self.delete_entry(event.entry) # Check if a node has a certain event def has_event(self,event, node_id): return self.table.get(node_id, event.node) >= event.time def send_to_node(self, node_id): # Don't send anything if the node is this if node_id == self.id: return partial = [] for event in self.events: if not isinstance(event, Event): continue if not self.has_event(event, node_id): partial.append(event.to_JSON()) data = { 'type': 'sync', 'node_id': self.id, 'table': self.table.to_JSON(), 'events': partial, } self.send(node_id, json.dumps(data)) def add_entry(self, entry): event = Event(MessageTypes.Insert, time.time(), self.id, entry) self.table.update(self.id, time.time() + 0.1) event.apply(self.entry_set, self) self.events.append(event) for id in entry.participants: if not id == self.id: self.send_to_node(id) def delete_entry(self, entry, exclude=[]): event = Event(MessageTypes.Delete, time.time(), self.id, entry) self.table.update(self.id, time.time() + 0.1) event.apply(self.entry_set, self) self.events.append(event) for id in entry.participants: if not id == self.id: if not id in exclude: self.send_to_node(id) def kill_thread(self): self.thread.terminate()
def function_handler(event): start_tstamp = time.time() log_level = event['log_level'] cloud_logging_config(log_level) logger.debug("Action handler started") extra_env = event.get('extra_env', {}) os.environ.update(extra_env) os.environ.update({'LITHOPS_FUNCTION': 'True', 'PYTHONUNBUFFERED': 'True'}) os.environ.pop('LITHOPS_TOTAL_EXECUTORS', None) config = event['config'] call_id = event['call_id'] job_id = event['job_id'] executor_id = event['executor_id'] exec_id = "{}/{}/{}".format(executor_id, job_id, call_id) logger.info("Execution-ID: {}".format(exec_id)) runtime_name = event['runtime_name'] runtime_memory = event['runtime_memory'] execution_timeout = event['execution_timeout'] logger.debug("Runtime name: {}".format(runtime_name)) logger.debug("Runtime memory: {}MB".format(runtime_memory)) logger.debug("Function timeout: {}s".format(execution_timeout)) func_key = event['func_key'] data_key = event['data_key'] data_byte_range = event['data_byte_range'] storage_config = extract_storage_config(config) internal_storage = InternalStorage(storage_config) call_status = CallStatus(config, internal_storage) call_status.response['host_submit_tstamp'] = event['host_submit_tstamp'] call_status.response['worker_start_tstamp'] = start_tstamp context_dict = { 'python_version': os.environ.get("PYTHON_VERSION"), 'call_id': call_id, 'job_id': job_id, 'executor_id': executor_id, 'activation_id': os.environ.get('__PW_ACTIVATION_ID') } call_status.response.update(context_dict) show_memory_peak = strtobool(os.environ.get('SHOW_MEMORY_PEAK', 'False')) try: if version.__version__ != event['lithops_version']: msg = ( "Lithops version mismatch. Host version: {} - Runtime version: {}" .format(event['lithops_version'], version.__version__)) raise RuntimeError('HANDLER', msg) # send init status event call_status.send('__init__') # call_status.response['free_disk_bytes'] = free_disk_space("/tmp") custom_env = { 'LITHOPS_CONFIG': json.dumps(config), 'LITHOPS_EXECUTION_ID': exec_id, 'PYTHONPATH': "{}:{}".format(os.getcwd(), LITHOPS_LIBS_PATH) } os.environ.update(custom_env) jobrunner_stats_dir = os.path.join(STORAGE_FOLDER, storage_config['bucket'], JOBS_PREFIX, executor_id, job_id, call_id) os.makedirs(jobrunner_stats_dir, exist_ok=True) jobrunner_stats_filename = os.path.join(jobrunner_stats_dir, 'jobrunner.stats.txt') jobrunner_config = { 'lithops_config': config, 'call_id': call_id, 'job_id': job_id, 'executor_id': executor_id, 'func_key': func_key, 'data_key': data_key, 'log_level': log_level, 'data_byte_range': data_byte_range, 'output_key': create_output_key(JOBS_PREFIX, executor_id, job_id, call_id), 'stats_filename': jobrunner_stats_filename } if show_memory_peak: mm_handler_conn, mm_conn = Pipe() memory_monitor = Thread(target=memory_monitor_worker, args=(mm_conn, )) memory_monitor.start() handler_conn, jobrunner_conn = Pipe() jobrunner = JobRunner(jobrunner_config, jobrunner_conn, internal_storage) logger.debug('Starting JobRunner process') local_execution = strtobool( os.environ.get('__PW_LOCAL_EXECUTION', 'False')) jrp = Thread(target=jobrunner.run) if local_execution else Process( target=jobrunner.run) jrp.start() jrp.join(execution_timeout) logger.debug('JobRunner process finished') if jrp.is_alive(): # If process is still alive after jr.join(job_max_runtime), kill it try: jrp.terminate() except Exception: # thread does not have terminate method pass msg = ('Function exceeded maximum time of {} seconds and was ' 'killed'.format(execution_timeout)) raise TimeoutError('HANDLER', msg) if show_memory_peak: mm_handler_conn.send('STOP') memory_monitor.join() peak_memory_usage = int(mm_handler_conn.recv()) logger.info("Peak memory usage: {}".format( sizeof_fmt(peak_memory_usage))) call_status.response['peak_memory_usage'] = peak_memory_usage if not handler_conn.poll(): logger.error( 'No completion message received from JobRunner process') logger.debug('Assuming memory overflow...') # Only 1 message is returned by jobrunner when it finishes. # If no message, this means that the jobrunner process was killed. # 99% of times the jobrunner is killed due an OOM, so we assume here an OOM. msg = 'Function exceeded maximum memory and was killed' raise MemoryError('HANDLER', msg) if os.path.exists(jobrunner_stats_filename): with open(jobrunner_stats_filename, 'r') as fid: for l in fid.readlines(): key, value = l.strip().split(" ", 1) try: call_status.response[key] = float(value) except Exception: call_status.response[key] = value if key in [ 'exception', 'exc_pickle_fail', 'result', 'new_futures' ]: call_status.response[key] = eval(value) except Exception: # internal runtime exceptions print('----------------------- EXCEPTION !-----------------------', flush=True) traceback.print_exc(file=sys.stdout) print('----------------------------------------------------------', flush=True) call_status.response['exception'] = True pickled_exc = pickle.dumps(sys.exc_info()) pickle.loads( pickled_exc) # this is just to make sure they can be unpickled call_status.response['exc_info'] = str(pickled_exc) finally: call_status.response['worker_end_tstamp'] = time.time() call_status.send('__end__') for key in extra_env: os.environ.pop(key) logger.info("Finished")
class MainWindow: SCRIPT_FILE = 'script.py' CONFIG_FILE = 'config.cfg' MODEL_DIR = "models/" #initialize the class, set up all GUI widgets and variables def __init__(self,parent): #widget variables self.inputsequence_path = StringVar() self.outputdirectory_path = StringVar() self.inputsequence_file = StringVar() self.outputdirectory_dir = StringVar() self.model = StringVar() self.kmers = IntVar() self.spacelen = IntVar() self.spacepos = IntVar() self.startpos = IntVar() self.endpos = IntVar() self.creategraphs = BooleanVar() self.topcut = IntVar() self.botcut = IntVar() self.keepseqs = BooleanVar() self.keeprvals = BooleanVar() self.progress = StringVar() #thread for batch self.script_thread = Thread(target=self.run_script) # self.batch_process = Process(target=self.run_batch) #initialize gui self.initfileframe(parent) self.initparamframe(parent) self.initselectframe(parent) self.initoptionsframe(parent) self.initmsgframe(parent) self.initbottombar(parent) self.progress.set("0 %") #file selection frame def initfileframe(self, parent): self.fileframe = Frame(parent) self.fileframe.grid(column=0, row=0, sticky=W, columnspan=4) self.btn_opensequence = Button(self.fileframe, width=12, text="open sequence", command=self.clickopensequence) self.btn_opensequence.grid(column=0, row=0) self.btn_outputdir = Button(self.fileframe, width=12, text="output directory", command=self.clickoutputdir) self.btn_outputdir.grid(column=0, row=1) self.ent_opensequence = Entry(self.fileframe, width=40, textvariable=self.inputsequence_file) self.ent_opensequence.grid(column=1, row=0) self.ent_outputdir = Entry(self.fileframe, width=40, textvariable=self.outputdirectory_dir) self.ent_outputdir.grid(column=1, row=1) self.lbl_models = Label(self.fileframe, width=12, text="Models:") self.lbl_models.grid(column=0, row=2, sticky=W) self.cmb_models = ttk.Combobox(self.fileframe, state='readonly', textvariable=self.model) self.cmb_models.grid(column=1, row=2, sticky=W) self.cmb_models['values'] = self.populatemodels() self.btn_loadsettings = Button(self.fileframe, width=12,text="Load settings", command=self.loadsettings) self.btn_loadsettings.grid(column=3, row=0, padx=(20,10), sticky=E) self.btn_setsettings = Button(self.fileframe, width=12, text="Set Settings", command=self.setsettings) self.btn_setsettings.grid(column=3, row=1, padx=(20,10),sticky=E) #parameter frame def initparamframe(self, parent): self.paramframe = LabelFrame(parent, text="Parameters") self.paramframe.grid(column=0, row=4, sticky=NW) self.lbl_kmers = Label(self.paramframe, text="Kmers:") self.lbl_kmers.grid(column=0, row=0) self.ent_kmers = Entry(self.paramframe, width=5, textvariable=self.kmers) self.ent_kmers.grid(column=1, row=0) self.lbl_spacelen = Label(self.paramframe, text="Spacer length:") self.lbl_spacelen.grid(column=0, row=1) self.ent_spacelen = Entry(self.paramframe, width=5, textvariable=self.spacelen) self.ent_spacelen.grid(column=1, row=1) self.lbl_spacepos = Label(self.paramframe, text="Insert Spacer at:") self.lbl_spacepos.grid(column=0, row=2) self.ent_spacepos = Entry(self.paramframe, width=5, textvariable=self.spacepos) self.ent_spacepos.grid(column=1, row=2) self.lbl_startpos = Label(self.paramframe, text="Starting at") self.lbl_startpos.grid(column=0, row=3) self.ent_startpos = Entry(self.paramframe, width=5, textvariable=self.startpos) self.ent_startpos.grid(column=1, row=3) self.lbl_endpos = Label(self.paramframe, text="Ending at") self.lbl_endpos.grid(column=0, row=4) self.ent_endpos = Entry(self.paramframe, width=5, textvariable=self.endpos) self.ent_endpos.grid(column=1, row=4) #selection frame def initselectframe(self, parent): self.selectframe = LabelFrame(parent, text="Graphs") self.selectframe.grid(column=1, row=4, sticky=NW) self.chk_creategraphs = Checkbutton(self.selectframe, text="Create Graphs", variable=self.creategraphs) self.chk_creategraphs.grid(column=0, row=0) self.lbl_forrvals = Label(self.selectframe, text="For R-Values:") self.lbl_forrvals.grid(column=0, row=1) self.lbl_toppercent = Label(self.selectframe, text="Top % ") self.lbl_toppercent.grid(column=0, row=2) self.ent_toppercent = Entry(self.selectframe, width=5, textvariable=self.topcut) self.ent_toppercent.grid(column=1, row=2) self.lbl_botpercent = Label(self.selectframe, text="Bottom % ") self.lbl_botpercent.grid(column=0, row=3) self.ent_botpercent = Entry(self.selectframe, width=5, textvariable=self.botcut) self.ent_botpercent.grid(column=1, row=3) #extra option frame def initoptionsframe(self, parent): self.optionsframe = LabelFrame(parent, text="Options") self.optionsframe.grid(column=2, row=4, sticky=NW) self.chk_keepseqs = Checkbutton(self.optionsframe, text="Keep all Sequences") self.chk_keepseqs.config(variable=self.keepseqs, onvalue=True, offvalue=False) self.chk_keepseqs.grid(column=0, row=0, sticky=W) self.chk_keeprvals = Checkbutton(self.optionsframe, text="Keep all R-Values") self.chk_keeprvals.config(variable=self.keeprvals, onvalue=True, offvalue=False) self.chk_keeprvals.grid(column=0, row=1, sticky=W) #message box frame def initmsgframe(self, parent): self.msgframe = Frame(parent) self.msgframe.grid(column=0, row=5, columnspan=4) self.msgbox = Text(self.msgframe, height=10, width=50)#, state=DISABLED) self.msgbox.pack(side=LEFT, fill=Y) self.scroll = Scrollbar(self.msgframe) self.scroll.pack(side=RIGHT, fill=Y) self.scroll.config(command=self.msgbox.yview) self.msgbox.config(yscrollcommand=self.scroll.set) #bottom progress start/stop bar def initbottombar(self, parent): self.bottombarframe = Frame(parent) self.bottombarframe.grid(column=0, row=6, columnspan=4) self.btn_start = Button(self.bottombarframe, width=10, text="Start", command=self.start) self.btn_start.pack(side=LEFT) self.lbl_progress = Label(self.bottombarframe, width=10, textvariable=self.progress) self.lbl_progress.pack(side=LEFT) self.btn_stop = Button(self.bottombarframe, width=10, text="Stop") self.btn_stop.pack(side=LEFT) #BUTTON METHODS##################### def start(self): self.msgbox.insert(END, "Starting...") self.script_thread.start() # self.batch_process.start() root.update_idletasks() def stop(self): self.msgbox.insert(END, "Stop Process") self.script_thread.terminate() # self.batch_process.terminate() sys.exit() def run_script(self): process = subprocess.Popen([MainWindow.SCRIPT_FILE], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) outmsg = process.stdout.read() self.msgbox.insert(END,process.returncode) def loadsettings(self): config = ConfigParser.ConfigParser() config.read(MainWindow.CONFIG_FILE) self.inputsequence_path.set(config.get('Files', 'input file')) self.inputsequence_file.set(os.path.basename(config.get('Files', 'input file'))) self.outputdirectory_path.set(config.get('Files', 'output directory')) self.outputdirectory_dir.set(os.path.basename(config.get('Files', 'output directory'))) self.cmb_models.set(os.path.basename(config.get('Files', 'model file'))) self.kmers.set(config.getint('Params', 'kmers')) self.spacelen.set(config.getint('Params', 'spacer length')) self.spacepos.set(config.getint('Params', 'spacer after position')) self.startpos.set(config.getint('Params', 'starting at position')) self.endpos.set(config.getint('Params', 'ending at position')) self.creategraphs.set(config.getboolean('Graph', 'create graphs')) self.topcut.set(config.getint('Graph', 'top')) self.botcut.set(config.getint('Graph', 'bottom')) self.keepseqs.set(config.getboolean('Options', 'keep all sequences')) self.keeprvals.set(config.getboolean('Options', 'keep all rvalues')) def setsettings(self): config = ConfigParser.ConfigParser() config.read(MainWindow.CONFIG_FILE) config.set('Files', 'input file', self.inputsequence_path.get()) config.set('Files', 'output directory', self.outputdirectory_path.get()) config.set('Files', 'model file', MainWindow.MODEL_DIR + self.model.get()) config.set('Params', 'kmers', self.kmers.get()) config.set('Params', 'spacer length', self.spacelen.get()) config.set('Params', 'spacer after position', self.spacepos.get()) config.set('Params', 'starting at position', self.startpos.get()) config.set('Params', 'ending at position', self.endpos.get()) config.set('Graph', 'create graphs', self.creategraphs.get()) config.set('Graph', 'top', self.topcut.get()) config.set('Graph', 'bottom', self.botcut.get()) config.set('Options', 'keep all sequences', self.keepseqs.get()) config.set('Options', 'keep all rvalues', self.keeprvals.get()) ks = os.path.basename(config.get('Options', 'sequences file')) rv = os.path.basename(config.get('Options', 'rvalues file')) gr = os.path.basename(config.get('Options', 'graph data file')) config.set('Options', 'sequences file', self.outputdirectory_dir.get() + '/' + ks) config.set('Options', 'rvalues file', self.outputdirectory_dir.get() + '/' + rv) config.set('Options', 'graph data file', self.outputdirectory_dir.get() + '/' + gr) with open(MainWindow.CONFIG_FILE, 'wb') as configfile: config.write(configfile) def clickopensequence(self): self.inputsequence_path.set(tkFileDialog.askopenfilename()) self.inputsequence_file.set(os.path.basename(self.inputsequence_path.get())) def clickoutputdir(self): self.outputdirectory_path.set(tkFileDialog.askdirectory()) self.outputdirectory_dir.set(os.path.basename(self.outputdirectory_path.get())) #OTHER METHODS def populatemodels(self): modellist=[] for files in os.listdir(MainWindow.MODEL_DIR): modellist.append(files) return modellist