Exemple #1
0
class FPSDataLimit(Block):
    ''' This block limits the output update to a certain framerate. '''
    Block.alias('fps_data_limit')

    Block.config('fps', 'Maximum framerate.')

    Block.input_is_variable('Signals to decimate.', min=1)
    Block.output_is_variable('Decimated signals.')

    def init(self):
        self.state.last_timestamp = None

    def update(self):
        should_update = False

        last = self.state.last_timestamp
        current = max(self.get_input_signals_timestamps())

        if last is None:
            should_update = True
            self.state.last_timestamp = current
        else:
            fps = self.config.fps
            delta = 1.0 / fps
            difference = current - last
            if difference > delta:
                should_update = True
                self.state.last_timestamp = current

        if not should_update:
            return
        # Just copy the input to the output
        for i in range(self.num_input_signals()):
            self.set_output(i, self.get_input(i), self.get_input_timestamp(i))
Exemple #2
0
class ASync(Block):
    ''' 
      The first signal is the "master".
      Waits that all signals are perceived once.
      Then it creates one event every time the master arrives.
    '''
    Block.alias('async')

    Block.input_is_variable(
        'Signals to (a)synchronize. The first is the master.', min=2)
    Block.output_is_variable('Synchronized signals.')

    def init(self):
        self.state.last_sent_timestamp = None

    def update(self):
        self.state.last_timestamp = None

        # No signal until everybody is ready
        if not self.all_input_signals_ready():
            return

        # No signal unless the master is ready
        master_timestamp = self.get_input_timestamp(0)
        if self.state.last_timestamp == master_timestamp:
            return

        self.state.last_timestamp = master_timestamp

        # Write all signals using master's timestamp
        for s in self.get_input_signals_names():
            self.set_output(s, self.get_input(s), master_timestamp)
Exemple #3
0
class Wait(Block):
    ''' 
        This block waits a given number of updates before transmitting the 
        output signal.
    '''
    Block.alias('wait')

    Block.config('n', 'Number of updates to wait at the beginning.')

    Block.input_is_variable('Arbitrary signals.')
    Block.output_is_variable('Copy of the signals, minus the first '
                             '*n* updates.')

    def init(self):
        self.state.count = 0

    def update(self):
        count = self.state.count

        # make something happen after we have waited enough
        if count >= self.config.n:
            # Just copy the input to the output
            for i in range(self.num_input_signals()):
                self.set_output(i, self.get_input(i),
                                self.get_input_timestamp(i))

        self.state.count = count + 1
Exemple #4
0
class Identity(Block):
    ''' 
        This block outputs the inputs, unchanged. 
    '''

    Block.alias('identity')
    Block.input_is_variable('Input signals.', min=1)
    Block.output_is_variable('Output signals, equal to input.')

    def update(self):
        # Just copy the input to the output
        for i in range(self.num_input_signals()):
            self.set_output(i, self.get_input(i), self.get_input_timestamp(i))
Exemple #5
0
class AllReady(Block):
    ''' 
        This block outputs the inputs, unchanged. 
    '''

    Block.alias('all_ready')

    Block.input_is_variable('Input signals.', min=1)
    Block.output_is_variable('Output signals, equal to input.')

    def update(self):
        if not self.all_input_signals_ready():
            return

        for i in range(self.num_input_signals()):
            if self.input_update_available(i):
                t, value = self.get_input_ts_and_value(i)
                self.set_output(i, value, t)
Exemple #6
0
class FPSLimit(Block):
    ''' This block limits the output update to a certain *realtime* framerate.
    
    Note that this uses realtime wall clock time -- not the data time!
    This is mean for real-time applications, such as visualization.'''

    Block.alias('fps_limit')

    Block.config('fps', 'Realtime fps limit.')

    Block.input_is_variable('Arbitrary signals.')
    Block.output_is_variable('Arbitrary signals with limited framerate.')

    def init(self):
        self.state.last_timestamp = None

    def update(self):
        should_update = False

        last = self.state.last_timestamp
        current = time.time()

        if last is None:
            should_update = True
            self.state.last_timestamp = current
        else:
            fps = self.config.fps
            delta = 1.0 / fps
            difference = current - last
            #print "difference: %s ~ %s" % (difference, delta)
            if difference > delta:
                should_update = True
                self.state.last_timestamp = current

        if not should_update:
            return

        # Just copy the input to the output
        for i in range(self.num_input_signals()):
            self.set_output(i, self.get_input(i), self.get_input_timestamp(i))
Exemple #7
0
class Sync(Generator):
    ''' 
    This block synchronizes a set of streams to the first stream (the master).
    
    The first signal is called the "master" signal.
    The other (N-1) are slaves.
    
    We guarantee that:
    
    - if the slaves are faster than the master,
      then we output exactly the same.
      
    Example diagrams: ::
      
        Master  *  *  *   *   *
        Slave   ++++++++++++++++
        
        Master  *  *  *   *   *
        output? v  v  x   v  
        Slave   +    +      +   
        output? v    v      v
    '''
    Block.alias('sync')

    Block.input_is_variable('Signals to synchronize. The first is the master.',
                            min=2)
    Block.output_is_variable('Synchronized signals.')

    def init(self):
        # output signals get the same name as the inputs
        names = self.get_input_signals_names()

        # create a state for each signal: it is an array
        # of tuples (timestamp, tuple)
        queues = {}
        for signal in names:
            queues[signal] = []

        # note in all queues,
        # [(t0,...), (t1,...), ... , (tn,...) ]
        # and we have t0 > tn
        # The chronologically first (oldest) is queue[-1]
        # You get one out using queue.pop()
        # You insert one with queue.insert(0,...)

        self.set_state('queues', queues)
        self.state.already_seen = {}

        self.set_state('master', names[0])
        self.set_state('slaves', names[1:])

        # The output is an array of tuple (timestamp, values)
        # [
        #    (timestamp1, [value1,value2,value3,...]),
        #    (timestamp1, [value1,value2,value3,...])
        # ]#
        self.set_state('output', [])

    def update(self):
        def debug(s):
            if False:  # XXX: use facilities
                print('sync %s %s' % (self.name, s))

        output = self.get_state('output')
        queues = self.get_state('queues')
        names = self.get_input_signals_names()
        # for each input signal, put its value in the queues
        # if it is not already present
        for i, name in enumerate(names):
            #            Commenting this; we clarified 0 = eternity; None = no signal yet
            if not self.input_signal_ready(i):
                debug('Ignoring signal %r because timestamp is None.' % name)
                continue

            current_timestamp = self.get_input_timestamp(i)
            current_value = self.get_input(i)

            if (name in self.state.already_seen
                    and self.state.already_seen[name] == current_timestamp):
                continue
            else:
                self.state.already_seen[name] = current_timestamp

            queue = queues[name]
            # if there is nothing in the queue
            # or this is a new sample
            if ((len(queue) == 0) or newest(queue).timestamp !=
                    current_timestamp):  # new sample
                debug("Inserting signal '%s'  ts %s (queue len: %d)" %
                      (name, current_timestamp, len(queue)))
                # debug('Before the queue is: %s' % queue)
                add_last(
                    queue,
                    Sample(timestamp=current_timestamp, value=current_value))

                # debug('Now the queue is: %s' % queue)

        master = self.get_state('master')
        master_queue = queues[master]
        slaves = self.get_state('slaves')

        # if there is more than one value in each slave
        if len(master_queue) > 1:
            val = master_queue.pop()
            debug('DROPPING master (%s) ts =%s' % (master, val.timestamp))

        # Now check whether all slaves signals are >= the master
        # If so, output a synchronized sample.
        if master_queue:
            all_ready = True
            master_timestamp = master_queue[-1].timestamp
            # print "Master timestamp: %s" % (master_timestamp)
            for slave in slaves:
                slave_queue = queues[slave]
                # remove oldest
                while (len(slave_queue) > 1
                       and oldest(slave_queue).timestamp < master_timestamp
                       and oldest(slave_queue).timestamp != ETERNITY):
                    debug("DROP one from %s" % slave)
                    slave_queue.pop()

                if not slave_queue:
                    # or (master_timestamp > slave_queue[-1].timestamp):
                    all_ready = False
                    # its_ts = map(lambda x:x.timestamp, slave_queue)
                    # print "Slave %s not ready: %s" %(slave, its_ts)
                    break

            if all_ready:
                debug("**** Ready: master timestamp %s " % (master_timestamp))
                master_value = master_queue.pop().value
                output_values = [master_value]
                for slave in slaves:
                    # get the freshest still after the master
                    slave_queue = queues[slave]
                    slave_timestamp, slave_value = slave_queue.pop()
                    # print('Slave, %s %s ' % (slave, slave_timestamp))
                    if slave_timestamp == ETERNITY:
                        slave_queue.append((slave_timestamp, slave_value))
                    # # not true anymore, assert slave_timestamp >=
                    # master_timestamp
                    # difference = slave_timestamp - master_timestamp
                    # debug(" - %s timestamp %s diff %s" %
                    #      (slave, slave_timestamp, difference))
                    output_values.append(slave_value)
                output.insert(0, (master_timestamp, output_values))

        # XXX XXX not really sure here
        # if master has more than one sample, then drop the first one

        # if we have something to output, do it
        if output:
            timestamp, values = output.pop()
            # FIXME: had to remove this for Vehicles simulation
            # assert timestamp > 0
            debug("---------------- @ %s" % timestamp)
            for i in range(self.num_output_signals()):
                self.set_output(i, values[i], timestamp)

    def next_data_status(self):
        output = self.get_state('output')
        if not output:  # no output ready
            return (False, None)
        else:
            timestamp = self.output[-1][0]
            return (True, timestamp)
Exemple #8
0
 class MyBlockA(Block):
     Block.input_is_variable()
     Block.output_is_variable()
Exemple #9
0
 class MyBlock(Block):
     Block.output_is_variable()
Exemple #10
0
 class MyBlock(Block):
     Block.input('x')
     Block.output_is_variable()