Exemple #1
0
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()
Exemple #2
0
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()
Exemple #3
0
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()
Exemple #4
0
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()
Exemple #5
0
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
Exemple #7
0
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()
Exemple #8
0
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()
Exemple #9
0
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()
Exemple #10
0
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
Exemple #11
0
    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()
Exemple #12
0
    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()
Exemple #13
0
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
Exemple #14
0
        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()
Exemple #15
0
    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)
Exemple #16
0
    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)
Exemple #17
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)
Exemple #19
0
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()
Exemple #20
0
        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()
Exemple #21
0
    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
Exemple #22
0
    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()
Exemple #23
0
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()
Exemple #24
0
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)
Exemple #25
0
    

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()
Exemple #27
0
    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
Exemple #28
0
                    # 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(','))
Exemple #29
0
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)
Exemple #30
0
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()
Exemple #31
0
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)
Exemple #32
0
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)
Exemple #33
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()
Exemple #34
0
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
Exemple #35
0
		   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"
Exemple #36
0
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
Exemple #37
0
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()
Exemple #39
0
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,
    }
Exemple #40
0
    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
Exemple #41
0
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
Exemple #42
0
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)
Exemple #43
0
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
Exemple #45
0
     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()
                          
                            

                           
          
     
     
   

Exemple #46
0
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()
Exemple #48
0
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")
Exemple #49
0
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