Class: Orocos::Log::OutputPort

Inherits:
Object
  • Object
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

Instance Method Summary collapse

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


299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/orocos/log/task_context.rb', line 299

def initialize(task,stream)
    if !stream.respond_to?(:name) || !stream.respond_to?(:type) || !stream.respond_to?(:typename) || !stream.respond_to?(:metadata)
        raise "Cannot create OutputPort out of #{stream.class}"
    end
    @stream = stream
    @name = if stream..has_key? "rock_task_object_name"
                name = stream.["rock_task_object_name"]
                if !name || name.empty?
                    name = "#{stream.name.to_s}"
                    Log.warn "Stream name (#{stream.name}) has empty meta data assuming as PORTNAME \"#{name}\""
                end
                name
            else
                # backward compatibility
                name = stream.name.to_s.match(/\.(.*$)/)
                if name == nil
                    name = "#{stream.name.to_s}"
                    Log.warn "Stream name (#{stream.name}) does not follow the convention TASKNAME.PORTNAME, assuming as PORTNAME \"#{name}\""
                    name
                else
                    name[1]
                end
            end
    begin
        @type = stream.type
    rescue Exception => e
        raise InitializePortError.new( e.message, @name )
    end
    @type_name = stream.typename
    @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


158
159
160
# File 'lib/orocos/log/task_context.rb', line 158

def default_policy
  @default_policy
end

Instance Attribute Details

#connectionsObject (readonly)

connections between this port and InputPort ports that support a writer


132
133
134
# File 'lib/orocos/log/task_context.rb', line 132

def connections
  @connections
end

#current_dataObject (readonly)

Returns the value of attribute current_data


146
147
148
# File 'lib/orocos/log/task_context.rb', line 146

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)


155
156
157
# File 'lib/orocos/log/task_context.rb', line 155

def filter
  @filter
end

#last_updateObject (readonly)

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


144
145
146
# File 'lib/orocos/log/task_context.rb', line 144

def last_update
  @last_update
end

#nameObject (readonly)

name of the recorded port


123
124
125
# File 'lib/orocos/log/task_context.rb', line 123

def name
  @name
end

#readersObject (readonly)

number of readers which are using the port


141
142
143
# File 'lib/orocos/log/task_context.rb', line 141

def readers
  @readers
end

#streamObject (readonly)

dedicated stream for simulating the port


135
136
137
# File 'lib/orocos/log/task_context.rb', line 135

def stream
  @stream
end

#taskObject (readonly)

parent log task


138
139
140
# File 'lib/orocos/log/task_context.rb', line 138

def task
  @task
end

#trackedObject

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


120
121
122
# File 'lib/orocos/log/task_context.rb', line 120

def tracked
  @tracked
end

#typeObject (readonly)

name of the type as Typelib::Type object


126
127
128
# File 'lib/orocos/log/task_context.rb', line 126

def type
  @type
end

#type_nameObject (readonly)

name of the type as it is used in ruby


129
130
131
# File 'lib/orocos/log/task_context.rb', line 129

def type_name
  @type_name
end

Instance Method Details

#add_connection(connection) ⇒ Object


408
409
410
411
# File 'lib/orocos/log/task_context.rb', line 408

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

#aligned?Boolean

returns true if Log::Replay is aligned

Returns:

  • (Boolean)

480
481
482
# File 'lib/orocos/log/task_context.rb', line 480

def aligned?
    task.log_replay.aligned?
end

#clear_reader_buffersObject

Clears all reader buffers


473
474
475
476
477
# File 'lib/orocos/log/task_context.rb', line 473

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


418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
# File 'lib/orocos/log/task_context.rb', line 418

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


462
463
464
465
# File 'lib/orocos/log/task_context.rb', line 462

def disconnect_all
    @connections.clear
    @readers.clear
end

#doc?Boolean

Returns:

  • (Boolean)

489
490
491
# File 'lib/orocos/log/task_context.rb', line 489

def doc?
    false
end

#first_sample_posObject


242
243
244
# File 'lib/orocos/log/task_context.rb', line 242

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)

234
235
236
# File 'lib/orocos/log/task_context.rb', line 234

def force_local?
    return true
end

#full_nameObject

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


291
292
293
# File 'lib/orocos/log/task_context.rb', line 291

def full_name
    stream.name
end

#has_connection?(connection) ⇒ Boolean

Returns:

  • (Boolean)

404
405
406
# File 'lib/orocos/log/task_context.rb', line 404

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

#last_sample_posObject


238
239
240
# File 'lib/orocos/log/task_context.rb', line 238

def last_sample_pos
    task.log_replay.last_sample_pos stream
end

#metadataObject

returns the metadata associated with the underlying stream


286
287
288
# File 'lib/orocos/log/task_context.rb', line 286

def 
    stream.
end

#new_sampleObject

Returns a new sample object


468
469
470
# File 'lib/orocos/log/task_context.rb', line 468

def new_sample
    @type.new
end

#number_of_samplesObject

Returns the number of samples for the port.


485
486
487
# File 'lib/orocos/log/task_context.rb', line 485

def number_of_samples
    return @stream.size
end

#on_data(&block) ⇒ Object

Calls the provided block when data is replayed into this port


391
392
393
394
395
# File 'lib/orocos/log/task_context.rb', line 391

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


398
399
400
401
402
# File 'lib/orocos/log/task_context.rb', line 398

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

#orocos_type_nameObject


223
224
225
226
227
228
229
230
231
# File 'lib/orocos/log/task_context.rb', line 223

def orocos_type_name
    if  && .has_key?(:rock_orocos_type_name)
        [:rock_orocos_type_name]
    elsif type_name =~ /^(.*)_m$/
        $1
    else
        type_name
    end
end

#output?Boolean

Returns:

  • (Boolean)

493
494
495
# File 'lib/orocos/log/task_context.rb', line 493

def output?
    true
end

#pretty_print(pp) ⇒ Object

Pretty print for OutputPort.


264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/orocos/log/task_context.rb', line 264

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


358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/orocos/log/task_context.rb', line 358

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.


352
353
354
355
356
# File 'lib/orocos/log/task_context.rb', line 352

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.


337
338
339
340
341
342
343
# File 'lib/orocos/log/task_context.rb', line 337

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


413
414
415
# File 'lib/orocos/log/task_context.rb', line 413

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


246
247
248
# File 'lib/orocos/log/task_context.rb', line 246

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


445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
# File 'lib/orocos/log/task_context.rb', line 445

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)

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

def used?
    return @tracked
end