Class: Orocos::Log::OutputPort

Inherits:
InterfaceObject show all
Defined in:
lib/orocos/log/task_context.rb,
lib/orocos/async/orocos.rb

Overview

Simulates a port based on log files It has the same behavior like Orocos::OutputPorts

Defined Under Namespace

Classes: CodeBlockConnection, Connection

Class Attribute Summary collapse

Instance Attribute Summary collapse

Attributes inherited from InterfaceObject

#name, #orocos_type_name, #type, #type_name

Instance Method Summary collapse

Methods inherited from InterfaceObject

#guess_object_name, #guess_orocos_type_name

Constructor Details

#initialize(task, stream) ⇒ OutputPort

Creates a new object of OutputPort

task => simulated task for which the port shall be created stream => stream from which the port shall be created



354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/orocos/log/task_context.rb', line 354

def initialize(task, stream)
    super(stream)

    begin
        @type = stream.type
    rescue Exception => e
        raise InitializePortError.new( e.message, @name )
    end
    @task = task
    @connections = Set.new
    @current_data = nil
    @tracked = false
    @readers = Array.new
    @last_update = Time.now
end

Class Attribute Details

.default_policyObject

Returns the value of attribute default_policy



223
224
225
# File 'lib/orocos/log/task_context.rb', line 223

def default_policy
  @default_policy
end

Instance Attribute Details

#connectionsObject (readonly)

connections between this port and InputPort ports that support a writer



197
198
199
# File 'lib/orocos/log/task_context.rb', line 197

def connections
  @connections
end

#current_dataObject (readonly)

Returns the value of attribute current_data



211
212
213
# File 'lib/orocos/log/task_context.rb', line 211

def current_data
  @current_data
end

#filter(&block) ⇒ Object

filter for log data the filter is applied before all connections and readers are updated if you want to apply a filter only for one connection or one reader do not set the filter here. the filter must be a proc, lambda, method or object with a function named call. the signature must be: new_massage call(old_message)



220
221
222
# File 'lib/orocos/log/task_context.rb', line 220

def filter
  @filter
end

#last_updateObject (readonly)

returns the system time when the port was updated with new data



209
210
211
# File 'lib/orocos/log/task_context.rb', line 209

def last_update
  @last_update
end

#readersObject (readonly)

number of readers which are using the port



206
207
208
# File 'lib/orocos/log/task_context.rb', line 206

def readers
  @readers
end

#streamObject (readonly)

dedicated stream for simulating the port



200
201
202
# File 'lib/orocos/log/task_context.rb', line 200

def stream
  @stream
end

#taskObject (readonly)

parent log task



203
204
205
# File 'lib/orocos/log/task_context.rb', line 203

def task
  @task
end

#trackedObject

true –> this port shall be replayed even if there are no connections



194
195
196
# File 'lib/orocos/log/task_context.rb', line 194

def tracked
  @tracked
end

Instance Method Details

#add_connection(connection) ⇒ Object



442
443
444
445
# File 'lib/orocos/log/task_context.rb', line 442

def add_connection(connection)
    self.tracked = true
    @connections << connection
end

#aligned?Boolean

returns true if Log::Replay is aligned

Returns:

  • (Boolean)


514
515
516
# File 'lib/orocos/log/task_context.rb', line 514

def aligned?
    task.log_replay.aligned?
end

#clear_reader_buffersObject

Clears all reader buffers



507
508
509
510
511
# File 'lib/orocos/log/task_context.rb', line 507

def clear_reader_buffers
    @readers.each do |reader|
        reader.clear_buffer
    end
end

#connect_to(port = nil, policy = OutputPort::default_policy, &block) ⇒ Object

Register InputPort which is updated each time write is called



452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
# File 'lib/orocos/log/task_context.rb', line 452

def connect_to(port=nil,policy = OutputPort::default_policy,&block)
    port = if port.respond_to? :find_input_port
               #assuming port is a TaskContext
               if !(result = port.find_input_port(type,nil))
                   raise NotFound, "port #{name} does not match any port of the TaskContext #{port.name}."
               end
               result.to_orocos_port
           elsif port
               port.to_orocos_port
           end

    if block && !port
        Orocos::Log.warn "connect_to to a code block { |data| ... } is deprecated. Use #on_data instead."
    end

    self.tracked = true
    policy[:filter] = block if block
    if !port
      raise "Cannot set up connection no code block or port is given" unless block
      @connections << CodeBlockConnection::OnData.new(self,block)
    else
      raise "Cannot connect to #{port.class}" if(!port.instance_of?(Orocos::InputPort))
      @connections << Connection.new(self,port,policy)
      Log.info "setting connection: #{task.name}.#{name} --> #{port.task.name}.#{port.name}"
    end
end

#disconnect_allObject

Disconnects all ports and deletes all readers



496
497
498
499
# File 'lib/orocos/log/task_context.rb', line 496

def disconnect_all
    @connections.clear
    @readers.clear
end

#doc?Boolean

Returns:

  • (Boolean)


523
524
525
# File 'lib/orocos/log/task_context.rb', line 523

def doc?
    false
end

#first_sample_posObject



297
298
299
# File 'lib/orocos/log/task_context.rb', line 297

def first_sample_pos
    task.log_replay.first_sample_pos stream
end

#force_local?Boolean

if force_local? returns true this port will never be proxied by an orogen port proxy

Returns:

  • (Boolean)


289
290
291
# File 'lib/orocos/log/task_context.rb', line 289

def force_local?
    return true
end

#full_nameObject

Give the full name for this port. It is the stream name.



346
347
348
# File 'lib/orocos/log/task_context.rb', line 346

def full_name
    stream.name
end

#has_connection?(connection) ⇒ Boolean

Returns:

  • (Boolean)


438
439
440
# File 'lib/orocos/log/task_context.rb', line 438

def has_connection?(connection)
    @connections.include?(connection)
end

#last_sample_posObject



293
294
295
# File 'lib/orocos/log/task_context.rb', line 293

def last_sample_pos
    task.log_replay.last_sample_pos stream
end

#metadataObject

returns the metadata associated with the underlying stream



341
342
343
# File 'lib/orocos/log/task_context.rb', line 341

def 
    stream.
end

#new_sampleObject

Returns a new sample object



502
503
504
# File 'lib/orocos/log/task_context.rb', line 502

def new_sample
    @type.new
end

#number_of_samplesObject

Returns the number of samples for the port.



519
520
521
# File 'lib/orocos/log/task_context.rb', line 519

def number_of_samples
    return @stream.size
end

#on_data(&block) ⇒ Object

Calls the provided block when data is replayed into this port



425
426
427
428
429
# File 'lib/orocos/log/task_context.rb', line 425

def on_data(&block)
    connection = CodeBlockConnection::OnData.new(self,block)
    add_connection(connection)
    connection
end

#on_raw_data(&block) ⇒ Object

Calls the provided block when data is replayed into this port



432
433
434
435
436
# File 'lib/orocos/log/task_context.rb', line 432

def on_raw_data(&block)
    connection = CodeBlockConnection::OnRawData.new(self,block)
    add_connection(connection)
    connection
end

#output?Boolean

Returns:

  • (Boolean)


527
528
529
# File 'lib/orocos/log/task_context.rb', line 527

def output?
    true
end

#pretty_print(pp) ⇒ Object

Pretty print for OutputPort.



319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/orocos/log/task_context.rb', line 319

def pretty_print(pp)
    pp.text "#{task.name}.#{name}"
    pp.nest(2) do
        pp.breakable
        pp.text "tracked = #{@tracked}"
        pp.breakable
        pp.text "readers = #{@readers.size}"
        pp.breakable
        pp.text "filtered = #{(@filter!=nil).to_s}"
        @connections.each do |connection|
            pp.breakable
            if connection.is_a?(OutputPort::Connection)
                pp.text "connected to #{connection.port.task.name}.#{connection.port.name} (filtered = #{(connection.filter!=nil).to_s})"
            end
            if connection.is_a?(OutputPort::CodeBlockConnection)
                pp.text "connected to code block"
            end
        end
    end
end

#raw_readObject



392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
# File 'lib/orocos/log/task_context.rb', line 392

def raw_read
    if !used?
        raise "port #{full_name} is not replayed. Set tracked to true or use a port reader!"
    end
    if @sample_info && !@current_data
        stream, position = *@sample_info
        data = stream.read_one_raw_data_sample(position)
        if @filter
            filtered_data = @filter.call(data)

            if data.class != filtered_data.class
                Log.error "Filter block for port #{full_name} returned #{@current_data.class.name} but #{data.class.name} was expected."
                Log.error "If a statement like #{name} do |sample,port| or #{name}.connect_to(port) do |sample,port| is used, the code block always needs to return 'sample'!"
                Log.error "Disabling Filter for port #{full_name}"
                @filter = nil
                @current_data = data
            else
                @current_data = filtered_data
            end
        else
            @current_data = data
        end
    end
    @current_data
end

#readObject

Returns the current sample data.



386
387
388
389
390
# File 'lib/orocos/log/task_context.rb', line 386

def read
    if sample = raw_read
        return Typelib.to_ruby(sample)
    end
end

#reader(policy = OutputPort::default_policy, &block) ⇒ Object

Creates a new reader for the port.



371
372
373
374
375
376
377
# File 'lib/orocos/log/task_context.rb', line 371

def reader(policy = OutputPort::default_policy,&block)
    policy[:filter] = block if block
    self.tracked = true
    new_reader = OutputReader.new(self,policy)
    @readers << new_reader
    return new_reader
end

#remove_connection(connection) ⇒ Object



447
448
449
# File 'lib/orocos/log/task_context.rb', line 447

def remove_connection(connection)
    @connections.delete connection
end

#to_async(options = Hash.new) ⇒ Object



4
5
6
7
# File 'lib/orocos/async/orocos.rb', line 4

def to_async(options = Hash.new)
    self.tracked = true
    task.to_async(options).port(name,:type => type).wait
end

#to_orocos_portObject



301
302
303
# File 'lib/orocos/log/task_context.rb', line 301

def to_orocos_port
    self
end

#to_proxy(options = Hash.new) ⇒ Object



9
10
11
12
# File 'lib/orocos/async/orocos.rb', line 9

def to_proxy(options = Hash.new)
    self.tracked = true
    task.to_proxy(options).port(name,:type => type).wait
end

#update(sample_info) ⇒ Object



479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
# File 'lib/orocos/log/task_context.rb', line 479

def update(sample_info)
    @last_update = Time.now
    @current_data = nil
    @sample_info = sample_info

    @connections.each do |connection|
        connection.update
    end
    if !@readers.empty?
        sample = raw_read
        @readers.each do |reader|
            reader.update(sample)
        end
    end
end

#used?Boolean

Returns true if the port has at least one connection or tracked is set to true.

Returns:

  • (Boolean)


381
382
383
# File 'lib/orocos/log/task_context.rb', line 381

def used?
    return @tracked
end