Class: Orocos::OutputPort

Inherits:
Port
  • Object
show all
Includes:
OutputPortBase
Defined in:
lib/orocos/output_port.rb,
lib/orocos/ros/ports.rb,
lib/orocos/async/orocos.rb,
ext/rorocos/rorocos.cc

Overview

This class represents output ports on remote task contexts.

They are obtained from TaskContext#port or TaskContext#each_port

Direct Known Subclasses

RubyTasks::LocalOutputPort

Constant Summary

Constants inherited from Port

Port::CONNECTION_POLICY_OPTIONS, Port::DEFAULT_CONNECTION_POLICY, Port::MQ_RTT_DEFAULT_QUEUE_LENGTH

Constants included from PortBase

PortBase::D_DIFFERENT_HOSTS, PortBase::D_SAME_HOST, PortBase::D_SAME_PROCESS, PortBase::D_UNKNOWN

Instance Attribute Summary

Attributes included from PortBase

#model, #name, #orocos_type_name, #task, #type

Class Method Summary collapse

Instance Method Summary collapse

Methods included from OutputPortBase

#reader

Methods inherited from Port

#connected?, #create_stream, #default_ros_topic_name, #disconnect_all, #do_create_stream, #do_disconnect_all, #do_disconnect_from, #do_remove_stream, #doc, #doc?, #handle_mq_transport, prepare_policy, #refine_exceptions, #remove_stream, #to_orocos_port, transient_local_port_name, transport_name, #type_name, validate_policy

Methods included from PortBase

#==, #distance_to, #ensure_type_available, #full_name, #initialize, #log_metadata, #max_marshalling_size, #max_sizes, #new_sample, #to_s

Class Method Details

.reader_classObject

Used by OutputPortReadAccess to determine which output reader class should be used



15
# File 'lib/orocos/output_port.rb', line 15

def self.reader_class; OutputReader end

Instance Method Details

#connect_to(input_port, distance: D_UNKNOWN, **options) ⇒ Object

Connect this output port to an input port. options defines the connection policy for the connection. If a task is given instead of an input port the method will try to find the right input port by type and will raise an error if there are none or more than one matching input ports

The following options are available:

Data connections. In that connection, the reader will see only the last sample he received. Such a connection is set up with

input_port.connect_to output_port, :type => :data

Buffered connections. In that case, the reader will be able to read all the samples received since the last read. A buffer in between the output and input port will keep the samples that have not been read already. Such a connection is set up with:

output_port.connect_to input_port, :type => :buffer, :size => 10

Where the size option gives the size of the intermediate buffer. Note that new samples will be lost if they are received when the buffer is full.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/orocos/output_port.rb', line 40

def connect_to(input_port, distance: D_UNKNOWN, **options)
    if !input_port.respond_to?(:to_orocos_port)
        return super
    end

    input_port = input_port.to_orocos_port
    if !input_port.kind_of?(InputPort)
        raise ArgumentError, "an output port can only connect to an input port (got #{input_port})"
    elsif input_port.type.name != type.name
        raise ArgumentError, "trying to connect #{self}, an output port of type #{type.name}, to #{input_port}, an input port of type #{input_port.type.name}"
    end

    policy = Port.prepare_policy(**options)
    if distance == D_UNKNOWN
        distance = distance_to(input_port)
    end
    if distance == D_SAME_HOST
        policy = handle_mq_transport(input_port.full_name, policy)
    end
    if policy[:pull]
        input_port.blocking_read = true
    end

    begin
        refine_exceptions(input_port) do
            do_connect_to(input_port, policy)
        end
    rescue Orocos::ConnectionFailed => e
        if policy[:transport] == TRANSPORT_MQ && Orocos::MQueue.auto_fallback_to_corba?
            policy[:transport] = TRANSPORT_CORBA
            Orocos.warn "failed to create a connection from #{full_name} to #{input_port.full_name} using the MQ transport, falling back to CORBA"
            retry
        end
        raise
    end
            
    self
rescue Orocos::ConnectionFailed => e
    raise e, "failed to connect #{full_name} => #{input_port.full_name} with policy #{policy.inspect}"
end

#disconnect_from(input) ⇒ Object

Require this port to disconnect from the provided input port



82
83
84
85
86
87
88
89
90
91
# File 'lib/orocos/output_port.rb', line 82

def disconnect_from(input)
    if !input.respond_to?(:to_orocos_port)
        return super
    end

    input = input.to_orocos_port
    refine_exceptions(input) do
        do_disconnect_from(input)
    end
end

#do_connect_to(rinput_port, options) ⇒ Object

Actual implementation of #connect_to. Sanity checks are done in Ruby. Just create the connection.



439
440
441
442
443
444
445
446
447
448
449
450
451
452
# File 'ext/rorocos/rorocos.cc', line 439

static VALUE do_port_connect_to(VALUE routput_port, VALUE rinput_port, VALUE options)
{
    RTaskContext* out_task; VALUE out_name;
    tie(out_task, tuples::ignore, out_name) = getPortReference(routput_port);
    RTaskContext* in_task; VALUE in_name;
    tie(in_task, tuples::ignore, in_name) = getPortReference(rinput_port);

    RTT::corba::CConnPolicy policy = policyFromHash(options);
    bool result = corba_blocking_fct_call_with_result(bind(&_objref_CDataFlowInterface::createConnection,(_objref_CDataFlowInterface*)out_task->ports,
                StringValuePtr(out_name),in_task->ports,StringValuePtr(in_name),policy));
    if(!result)
        rb_raise(eConnectionFailed, "failed to connect ports");
    return Qnil;
}

#pretty_print(pp) ⇒ Object

:nodoc:



8
9
10
11
# File 'lib/orocos/output_port.rb', line 8

def pretty_print(pp) # :nodoc:
    pp.text "out "
    super
end

#publish_on_ros(topic_name = default_ros_topic_name, policy = Hash.new) ⇒ Object

Publishes this port on a ROS topic



10
11
12
13
14
15
# File 'lib/orocos/ros/ports.rb', line 10

def publish_on_ros(topic_name = default_ros_topic_name, policy = Hash.new)
    if topic_name.kind_of?(Hash)
        topic_name, policy = default_ros_topic_name, topic_name
    end
    create_stream(Orocos::TRANSPORT_ROS, topic_name, policy)
end

#to_async(options = Hash.new) ⇒ Object



66
67
68
69
70
71
# File 'lib/orocos/async/orocos.rb', line 66

def to_async(options = Hash.new)
    if use = options.delete(:use)
        Orocos::Async::CORBA::OutputPort.new(use,self,options)
    else to_async(Hash[:use => task.to_async].merge(options))
    end
end

#to_proxy(options = Hash.new) ⇒ Object



73
74
75
# File 'lib/orocos/async/orocos.rb', line 73

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

#unpublish_from_ros(topic_name = "#{task.name}/#{self.name}") ⇒ Object

Unpublishes this port from a ROS topic



18
19
20
# File 'lib/orocos/ros/ports.rb', line 18

def unpublish_from_ros(topic_name = "#{task.name}/#{self.name}")
    remove_stream(topic_name)
end